Merge branch 'next' of github.com:Budibase/budibase into lab-day-search
This commit is contained in:
commit
e661fe8cf2
|
@ -92,6 +92,16 @@ then `cd ` into your local copy.
|
||||||
|
|
||||||
### 3. Install and Build
|
### 3. Install and Build
|
||||||
|
|
||||||
|
To develop the Budibase platform you'll need [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) installed.
|
||||||
|
|
||||||
|
#### Quick method
|
||||||
|
|
||||||
|
`yarn setup` will check that all necessary components are installed and setup the repo for usage.
|
||||||
|
|
||||||
|
#### Manual method
|
||||||
|
|
||||||
|
The following commands can be executed to manually get Budibase up and running (assuming Docker/Docker Compose has been installed).
|
||||||
|
|
||||||
`yarn` to install project dependencies
|
`yarn` to install project dependencies
|
||||||
|
|
||||||
`yarn bootstrap` will install all budibase modules and symlink them together using lerna.
|
`yarn bootstrap` will install all budibase modules and symlink them together using lerna.
|
||||||
|
@ -112,10 +122,17 @@ To run the budibase server and builder in dev mode (i.e. with live reloading):
|
||||||
|
|
||||||
1. Open a new console
|
1. Open a new console
|
||||||
2. `yarn dev` (from root)
|
2. `yarn dev` (from root)
|
||||||
3. Access the builder on http://localhost:4001/_builder/
|
3. Access the builder on http://localhost:10000/builder
|
||||||
|
|
||||||
This will enable watch mode for both the builder app, server, client library and any component libraries.
|
This will enable watch mode for both the builder app, server, client library and any component libraries.
|
||||||
|
|
||||||
|
### 5. Cleanup
|
||||||
|
|
||||||
|
If you wish to delete all the apps created in development and reset the environment then run the following:
|
||||||
|
|
||||||
|
1. `yarn nuke:docker` will wipe all the Budibase services
|
||||||
|
2. `yarn dev` will restart all the services
|
||||||
|
|
||||||
## Data Storage
|
## Data Storage
|
||||||
|
|
||||||
When you are running locally, budibase stores data on disk using [PouchDB](https://pouchdb.com/), as well as some JSON on local files. After setting up budibase, you can find all of this data in the `~/.budibase` directory.
|
When you are running locally, budibase stores data on disk using [PouchDB](https://pouchdb.com/), as well as some JSON on local files. After setting up budibase, you can find all of this data in the `~/.budibase` directory.
|
||||||
|
|
|
@ -15,6 +15,22 @@
|
||||||
"created_at": "2021-04-14T16:20:04Z",
|
"created_at": "2021-04-14T16:20:04Z",
|
||||||
"repoId": 190729906,
|
"repoId": 190729906,
|
||||||
"pullRequestNo": 1383
|
"pullRequestNo": 1383
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aptkingston",
|
||||||
|
"id": 9075550,
|
||||||
|
"comment_id": 830252031,
|
||||||
|
"created_at": "2021-04-30T17:37:37Z",
|
||||||
|
"repoId": 190729906,
|
||||||
|
"pullRequestNo": 1431
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kevmodrome",
|
||||||
|
"id": 534488,
|
||||||
|
"comment_id": 830545461,
|
||||||
|
"created_at": "2021-05-01T05:27:53Z",
|
||||||
|
"repoId": 190729906,
|
||||||
|
"pullRequestNo": 1431
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -3,6 +3,8 @@
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": false,
|
"singleQuote": false,
|
||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"jsxBracketSameLine": false,
|
||||||
"plugins": ["prettier-plugin-svelte"],
|
"plugins": ["prettier-plugin-svelte"],
|
||||||
"svelteSortOrder" : "scripts-markup-styles"
|
"svelteSortOrder" : "options-scripts-markup-styles"
|
||||||
}
|
}
|
|
@ -59,6 +59,7 @@ services:
|
||||||
container_name: budi-redis-dev
|
container_name: budi-redis-dev
|
||||||
restart: always
|
restart: always
|
||||||
image: redis
|
image: redis
|
||||||
|
command: redis-server --requirepass ${REDIS_PASSWORD}
|
||||||
ports:
|
ports:
|
||||||
- "${REDIS_PORT}:6379"
|
- "${REDIS_PORT}:6379"
|
||||||
volumes:
|
volumes:
|
||||||
|
|
|
@ -23,6 +23,8 @@ services:
|
||||||
LOG_LEVEL: info
|
LOG_LEVEL: info
|
||||||
SENTRY_DSN: https://a34ae347621946bf8acded18e5b7d4b8@o420233.ingest.sentry.io/5338131
|
SENTRY_DSN: https://a34ae347621946bf8acded18e5b7d4b8@o420233.ingest.sentry.io/5338131
|
||||||
ENABLE_ANALYTICS: "true"
|
ENABLE_ANALYTICS: "true"
|
||||||
|
REDIS_URL: redis-service:6379
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
||||||
depends_on:
|
depends_on:
|
||||||
- worker-service
|
- worker-service
|
||||||
|
|
||||||
|
@ -43,6 +45,8 @@ services:
|
||||||
COUCH_DB_PASSWORD: ${COUCH_DB_PASSWORD}
|
COUCH_DB_PASSWORD: ${COUCH_DB_PASSWORD}
|
||||||
COUCH_DB_URL: http://${COUCH_DB_USER}:${COUCH_DB_PASSWORD}@couchdb-service:5984
|
COUCH_DB_URL: http://${COUCH_DB_USER}:${COUCH_DB_PASSWORD}@couchdb-service:5984
|
||||||
SELF_HOST_KEY: ${HOSTING_KEY}
|
SELF_HOST_KEY: ${HOSTING_KEY}
|
||||||
|
REDIS_URL: redis-service:6379
|
||||||
|
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
||||||
depends_on:
|
depends_on:
|
||||||
- minio-service
|
- minio-service
|
||||||
- couch-init
|
- couch-init
|
||||||
|
@ -100,8 +104,7 @@ services:
|
||||||
redis-service:
|
redis-service:
|
||||||
restart: always
|
restart: always
|
||||||
image: redis
|
image: redis
|
||||||
ports:
|
command: redis-server --requirepass ${REDIS_PASSWORD}
|
||||||
- "${REDIS_PORT}:6379"
|
|
||||||
volumes:
|
volumes:
|
||||||
- redis_data:/data
|
- redis_data:/data
|
||||||
|
|
||||||
|
|
|
@ -16,16 +16,16 @@ static_resources:
|
||||||
- name: local_services
|
- name: local_services
|
||||||
domains: ["*"]
|
domains: ["*"]
|
||||||
routes:
|
routes:
|
||||||
|
# special case to redirect specifically the route path
|
||||||
|
# to the builder, if this were a prefix then it would break minio
|
||||||
|
- match: { path: "/" }
|
||||||
|
redirect: { path_redirect: "/builder/" }
|
||||||
|
|
||||||
- match: { prefix: "/db/" }
|
- match: { prefix: "/db/" }
|
||||||
route:
|
route:
|
||||||
cluster: couchdb-service
|
cluster: couchdb-service
|
||||||
prefix_rewrite: "/"
|
prefix_rewrite: "/"
|
||||||
|
|
||||||
- match: { prefix: "/cache/" }
|
|
||||||
route:
|
|
||||||
cluster: redis-service
|
|
||||||
prefix_rewrite: "/"
|
|
||||||
|
|
||||||
- match: { prefix: "/api/admin/" }
|
- match: { prefix: "/api/admin/" }
|
||||||
route:
|
route:
|
||||||
cluster: worker-dev
|
cluster: worker-dev
|
||||||
|
@ -38,6 +38,13 @@ static_resources:
|
||||||
route:
|
route:
|
||||||
cluster: server-dev
|
cluster: server-dev
|
||||||
|
|
||||||
|
# the below three cases are needed to make sure
|
||||||
|
# all traffic prefixed for the builder is passed through
|
||||||
|
# correctly.
|
||||||
|
- match: { path: "/" }
|
||||||
|
route:
|
||||||
|
cluster: builder-dev
|
||||||
|
|
||||||
- match: { prefix: "/builder/" }
|
- match: { prefix: "/builder/" }
|
||||||
route:
|
route:
|
||||||
cluster: builder-dev
|
cluster: builder-dev
|
||||||
|
@ -47,10 +54,6 @@ static_resources:
|
||||||
cluster: builder-dev
|
cluster: builder-dev
|
||||||
prefix_rewrite: "/builder/"
|
prefix_rewrite: "/builder/"
|
||||||
|
|
||||||
# special case in dev to redirect no path to builder
|
|
||||||
- match: { path: "/" }
|
|
||||||
redirect: { path_redirect: "/builder/" }
|
|
||||||
|
|
||||||
# minio is on the default route because this works
|
# minio is on the default route because this works
|
||||||
# best, minio + AWS SDK doesn't handle path proxy
|
# best, minio + AWS SDK doesn't handle path proxy
|
||||||
- match: { prefix: "/" }
|
- match: { prefix: "/" }
|
||||||
|
@ -89,20 +92,6 @@ static_resources:
|
||||||
address: couchdb-service
|
address: couchdb-service
|
||||||
port_value: 5984
|
port_value: 5984
|
||||||
|
|
||||||
- name: redis-service
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
load_assignment:
|
|
||||||
cluster_name: redis-service
|
|
||||||
endpoints:
|
|
||||||
- lb_endpoints:
|
|
||||||
- endpoint:
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: redis-service
|
|
||||||
port_value: 6379
|
|
||||||
|
|
||||||
- name: server-dev
|
- name: server-dev
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
|
|
|
@ -21,7 +21,6 @@ static_resources:
|
||||||
cluster: app-service
|
cluster: app-service
|
||||||
prefix_rewrite: "/"
|
prefix_rewrite: "/"
|
||||||
|
|
||||||
# special case for presenting our static self hosting page
|
|
||||||
- match: { path: "/" }
|
- match: { path: "/" }
|
||||||
route:
|
route:
|
||||||
cluster: app-service
|
cluster: app-service
|
||||||
|
@ -41,11 +40,6 @@ static_resources:
|
||||||
cluster: worker-service
|
cluster: worker-service
|
||||||
prefix_rewrite: "/"
|
prefix_rewrite: "/"
|
||||||
|
|
||||||
- match: { prefix: "/cache/" }
|
|
||||||
route:
|
|
||||||
cluster: redis-service
|
|
||||||
prefix_rewrite: "/"
|
|
||||||
|
|
||||||
- match: { prefix: "/db/" }
|
- match: { prefix: "/db/" }
|
||||||
route:
|
route:
|
||||||
cluster: couchdb-service
|
cluster: couchdb-service
|
||||||
|
@ -117,18 +111,3 @@ static_resources:
|
||||||
address: couchdb-service
|
address: couchdb-service
|
||||||
port_value: 5984
|
port_value: 5984
|
||||||
|
|
||||||
- name: redis-service
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
load_assignment:
|
|
||||||
cluster_name: redis-service
|
|
||||||
endpoints:
|
|
||||||
- lb_endpoints:
|
|
||||||
- endpoint:
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: redis-service
|
|
||||||
port_value: 6379
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ MINIO_ACCESS_KEY=budibase
|
||||||
MINIO_SECRET_KEY=budibase
|
MINIO_SECRET_KEY=budibase
|
||||||
COUCH_DB_PASSWORD=budibase
|
COUCH_DB_PASSWORD=budibase
|
||||||
COUCH_DB_USER=budibase
|
COUCH_DB_USER=budibase
|
||||||
|
REDIS_PASSWORD=budibase
|
||||||
|
|
||||||
# This section contains variables that do not need to be altered under normal circumstances
|
# This section contains variables that do not need to be altered under normal circumstances
|
||||||
APP_PORT=4002
|
APP_PORT=4002
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const os = require("os")
|
||||||
|
const exec = require("child_process").exec
|
||||||
|
const fs = require("fs")
|
||||||
|
const platform = os.platform()
|
||||||
|
|
||||||
|
const windows = platform === "win32"
|
||||||
|
const mac = platform === "darwin"
|
||||||
|
const linux = platform === "linux"
|
||||||
|
|
||||||
|
function execute(command) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
exec(command, (err, stdout) => resolve(linux ? !!stdout : true))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function commandExistsUnix(command) {
|
||||||
|
const unixCmd = `command -v ${command} 2>/dev/null && { echo >&1 ${command}; exit 0; }`
|
||||||
|
return execute(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function commandExistsWindows(command) {
|
||||||
|
if (/[\x00-\x1f<>:"|?*]/.test(command)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return execute(`where ${command}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function commandExists(command) {
|
||||||
|
return windows ? commandExistsWindows(command) : commandExistsUnix(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
const docker = commandExists("docker")
|
||||||
|
const dockerCompose = commandExists("docker-compose")
|
||||||
|
if (docker && dockerCompose) {
|
||||||
|
console.log("Docker installed - continuing.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (mac) {
|
||||||
|
console.log(
|
||||||
|
"Please install docker by visiting: https://docs.docker.com/docker-for-mac/install/"
|
||||||
|
)
|
||||||
|
} else if (windows) {
|
||||||
|
console.log(
|
||||||
|
"Please install docker by visiting: https://docs.docker.com/docker-for-windows/install/"
|
||||||
|
)
|
||||||
|
} else if (linux) {
|
||||||
|
console.log("Beginning automated linux installation.")
|
||||||
|
await execute(`./hosting/scripts/linux/get-docker.sh`)
|
||||||
|
await execute(`./hosting/scripts/linux/get-docker-compose.sh`)
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
"Platform unknown - please look online for information about installing docker for our OS."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
console.log("Once installation complete please re-run the setup script.")
|
||||||
|
process.exit(-1)
|
||||||
|
}
|
||||||
|
init()
|
|
@ -14,9 +14,10 @@
|
||||||
"prettier-plugin-svelte": "^2.2.0",
|
"prettier-plugin-svelte": "^2.2.0",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rollup-plugin-replace": "^2.2.0",
|
"rollup-plugin-replace": "^2.2.0",
|
||||||
"svelte": "^3.30.0"
|
"svelte": "^3.38.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"setup": "./hosting/scripts/setup.js && yarn && yarn bootstrap && yarn build && yarn dev",
|
||||||
"bootstrap": "lerna link && lerna bootstrap",
|
"bootstrap": "lerna link && lerna bootstrap",
|
||||||
"build": "lerna run build",
|
"build": "lerna run build",
|
||||||
"initialise": "lerna run initialise",
|
"initialise": "lerna run initialise",
|
||||||
|
|
|
@ -1,18 +1,27 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/auth",
|
"name": "@budibase/auth",
|
||||||
"version": "0.0.1",
|
"version": "0.18.6",
|
||||||
"description": "Authentication middlewares for budibase builder and apps",
|
"description": "Authentication middlewares for budibase builder and apps",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"aws-sdk": "^2.901.0",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
|
"ioredis": "^4.27.1",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"koa-passport": "^4.1.4",
|
"koa-passport": "^4.1.4",
|
||||||
|
"node-fetch": "^2.6.1",
|
||||||
"passport-google-auth": "^1.0.2",
|
"passport-google-auth": "^1.0.2",
|
||||||
"passport-google-oauth": "^2.0.0",
|
"passport-google-oauth": "^2.0.0",
|
||||||
"passport-jwt": "^4.0.0",
|
"passport-jwt": "^4.0.0",
|
||||||
"passport-local": "^1.0.0",
|
"passport-local": "^1.0.0",
|
||||||
"uuid": "^8.3.2"
|
"sanitize-s3-objectkey": "^0.0.1",
|
||||||
|
"tar-fs": "^2.1.1",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
|
"zlib": "^1.0.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"ioredis-mock": "^5.5.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ const getConfigParams = ({ type, group, user }, otherProps = {}) => {
|
||||||
* @param {Object} scopes - the type, group and userID scopes of the configuration.
|
* @param {Object} scopes - the type, group and userID scopes of the configuration.
|
||||||
* @returns The most granular configuration document based on the scope.
|
* @returns The most granular configuration document based on the scope.
|
||||||
*/
|
*/
|
||||||
const determineScopedConfig = async function(db, { type, user, group }) {
|
const getScopedFullConfig = async function (db, { type, user, group }) {
|
||||||
const response = await db.allDocs(
|
const response = await db.allDocs(
|
||||||
getConfigParams(
|
getConfigParams(
|
||||||
{ type, user, group },
|
{ type, user, group },
|
||||||
|
@ -132,31 +132,40 @@ const determineScopedConfig = async function(db, { type, user, group }) {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
const configs = response.rows.map(row => {
|
|
||||||
|
function determineScore(row) {
|
||||||
const config = row.doc
|
const config = row.doc
|
||||||
|
|
||||||
// Config is specific to a user and a group
|
// Config is specific to a user and a group
|
||||||
if (config._id.includes(generateConfigID({ type, user, group }))) {
|
if (config._id.includes(generateConfigID({ type, user, group }))) {
|
||||||
config.score = 4
|
return 4
|
||||||
} else if (config._id.includes(generateConfigID({ type, user }))) {
|
} else if (config._id.includes(generateConfigID({ type, user }))) {
|
||||||
// Config is specific to a user only
|
// Config is specific to a user only
|
||||||
config.score = 3
|
return 3
|
||||||
} else if (config._id.includes(generateConfigID({ type, group }))) {
|
} else if (config._id.includes(generateConfigID({ type, group }))) {
|
||||||
// Config is specific to a group only
|
// Config is specific to a group only
|
||||||
config.score = 2
|
return 2
|
||||||
} else if (config._id.includes(generateConfigID({ type }))) {
|
} else if (config._id.includes(generateConfigID({ type }))) {
|
||||||
// Config is specific to a type only
|
// Config is specific to a type only
|
||||||
config.score = 1
|
return 1
|
||||||
}
|
}
|
||||||
return config
|
return 0
|
||||||
})
|
}
|
||||||
|
|
||||||
// Find the config with the most granular scope based on context
|
// Find the config with the most granular scope based on context
|
||||||
const scopedConfig = configs.sort((a, b) => b.score - a.score)[0]
|
const scopedConfig = response.rows.sort(
|
||||||
|
(a, b) => determineScore(a) - determineScore(b)
|
||||||
|
)[0]
|
||||||
|
|
||||||
return scopedConfig
|
return scopedConfig && scopedConfig.doc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getScopedConfig(db, params) {
|
||||||
|
const configDoc = await getScopedFullConfig(db, params)
|
||||||
|
return configDoc && configDoc.config ? configDoc.config : configDoc
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.getScopedConfig = getScopedConfig
|
||||||
exports.generateConfigID = generateConfigID
|
exports.generateConfigID = generateConfigID
|
||||||
exports.getConfigParams = getConfigParams
|
exports.getConfigParams = getConfigParams
|
||||||
exports.determineScopedConfig = determineScopedConfig
|
exports.getScopedFullConfig = getScopedFullConfig
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
|
function isTest() {
|
||||||
|
return (
|
||||||
|
process.env.NODE_ENV === "jest" ||
|
||||||
|
process.env.NODE_ENV === "cypress" ||
|
||||||
|
process.env.JEST_WORKER_ID != null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
JWT_SECRET: process.env.JWT_SECRET,
|
JWT_SECRET: process.env.JWT_SECRET,
|
||||||
COUCH_DB_URL: process.env.COUCH_DB_URL,
|
COUCH_DB_URL: process.env.COUCH_DB_URL,
|
||||||
SALT_ROUNDS: process.env.SALT_ROUNDS,
|
SALT_ROUNDS: process.env.SALT_ROUNDS,
|
||||||
|
REDIS_URL: process.env.REDIS_URL,
|
||||||
|
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
||||||
|
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
|
||||||
|
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
|
||||||
|
MINIO_URL: process.env.MINIO_URL,
|
||||||
|
isTest,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,6 @@ exports.compare = async (data, encrypted) => {
|
||||||
return bcrypt.compare(data, encrypted)
|
return bcrypt.compare(data, encrypted)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.newid = function() {
|
exports.newid = function () {
|
||||||
return v4().replace(/-/g, "")
|
return v4().replace(/-/g, "")
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,14 @@ module.exports = {
|
||||||
setDB(pouch)
|
setDB(pouch)
|
||||||
},
|
},
|
||||||
db: require("./db/utils"),
|
db: require("./db/utils"),
|
||||||
|
redis: {
|
||||||
|
Client: require("./redis"),
|
||||||
|
utils: require("./redis/utils"),
|
||||||
|
},
|
||||||
|
objectStore: {
|
||||||
|
...require("./objectStore"),
|
||||||
|
...require("./objectStore/utils"),
|
||||||
|
},
|
||||||
utils: {
|
utils: {
|
||||||
...require("./utils"),
|
...require("./utils"),
|
||||||
...require("./hashing"),
|
...require("./hashing"),
|
||||||
|
|
|
@ -3,11 +3,35 @@ const database = require("../db")
|
||||||
const { getCookie, clearCookie } = require("../utils")
|
const { getCookie, clearCookie } = require("../utils")
|
||||||
const { StaticDatabases } = require("../db/utils")
|
const { StaticDatabases } = require("../db/utils")
|
||||||
|
|
||||||
module.exports = (noAuthPatterns = []) => {
|
const PARAM_REGEX = /\/:(.*?)\//g
|
||||||
const regex = new RegExp(noAuthPatterns.join("|"))
|
|
||||||
|
function buildNoAuthRegex(patterns) {
|
||||||
|
return patterns.map(pattern => {
|
||||||
|
const isObj = typeof pattern === "object" && pattern.route
|
||||||
|
const method = isObj ? pattern.method : "GET"
|
||||||
|
let route = isObj ? pattern.route : pattern
|
||||||
|
|
||||||
|
const matches = route.match(PARAM_REGEX)
|
||||||
|
if (matches) {
|
||||||
|
for (let match of matches) {
|
||||||
|
route = route.replace(match, "/.*/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { regex: new RegExp(route), method }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = (noAuthPatterns = [], opts) => {
|
||||||
|
const noAuthOptions = noAuthPatterns ? buildNoAuthRegex(noAuthPatterns) : []
|
||||||
return async (ctx, next) => {
|
return async (ctx, next) => {
|
||||||
// the path is not authenticated
|
// the path is not authenticated
|
||||||
if (regex.test(ctx.request.url)) {
|
const found = noAuthOptions.find(({ regex, method }) => {
|
||||||
|
return (
|
||||||
|
regex.test(ctx.request.url) &&
|
||||||
|
ctx.request.method.toLowerCase() === method.toLowerCase()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
if (found != null) {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -30,10 +54,14 @@ module.exports = (noAuthPatterns = []) => {
|
||||||
if (ctx.isAuthenticated !== true) {
|
if (ctx.isAuthenticated !== true) {
|
||||||
ctx.isAuthenticated = false
|
ctx.isAuthenticated = false
|
||||||
}
|
}
|
||||||
|
|
||||||
return next()
|
return next()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ctx.throw(err.status || 403, err)
|
// allow configuring for public access
|
||||||
|
if (opts && opts.publicAllowed) {
|
||||||
|
ctx.isAuthenticated = false
|
||||||
|
} else {
|
||||||
|
ctx.throw(err.status || 403, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ async function authenticate(token, tokenSecret, profile, done) {
|
||||||
* from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.
|
* from couchDB rather than environment variables, using this factory is necessary for dynamically configuring passport.
|
||||||
* @returns Dynamically configured Passport Google Strategy
|
* @returns Dynamically configured Passport Google Strategy
|
||||||
*/
|
*/
|
||||||
exports.strategyFactory = async function(config) {
|
exports.strategyFactory = async function (config) {
|
||||||
try {
|
try {
|
||||||
const { clientID, clientSecret, callbackURL } = config
|
const { clientID, clientSecret, callbackURL } = config
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@ const env = require("../../environment")
|
||||||
|
|
||||||
exports.options = {
|
exports.options = {
|
||||||
secretOrKey: env.JWT_SECRET,
|
secretOrKey: env.JWT_SECRET,
|
||||||
jwtFromRequest: function(ctx) {
|
jwtFromRequest: function (ctx) {
|
||||||
return ctx.cookies.get(Cookies.Auth)
|
return ctx.cookies.get(Cookies.Auth)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.authenticate = async function(jwt, done) {
|
exports.authenticate = async function (jwt, done) {
|
||||||
try {
|
try {
|
||||||
return done(null, jwt)
|
return done(null, jwt)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ exports.options = {}
|
||||||
* @param {*} done - callback from passport to return user information and errors
|
* @param {*} done - callback from passport to return user information and errors
|
||||||
* @returns The authenticated user, or errors if they occur
|
* @returns The authenticated user, or errors if they occur
|
||||||
*/
|
*/
|
||||||
exports.authenticate = async function(email, password, done) {
|
exports.authenticate = async function (email, password, done) {
|
||||||
if (!email) return done(null, false, "Email Required.")
|
if (!email) return done(null, false, "Email Required.")
|
||||||
if (!password) return done(null, false, "Password Required.")
|
if (!password) return done(null, false, "Password Required.")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,240 @@
|
||||||
|
const sanitize = require("sanitize-s3-objectkey")
|
||||||
|
const AWS = require("aws-sdk")
|
||||||
|
const stream = require("stream")
|
||||||
|
const fetch = require("node-fetch")
|
||||||
|
const tar = require("tar-fs")
|
||||||
|
const zlib = require("zlib")
|
||||||
|
const { promisify } = require("util")
|
||||||
|
const { join } = require("path")
|
||||||
|
const fs = require("fs")
|
||||||
|
const env = require("../environment")
|
||||||
|
const { budibaseTempDir, ObjectStoreBuckets } = require("./utils")
|
||||||
|
const { v4 } = require("uuid")
|
||||||
|
|
||||||
|
const streamPipeline = promisify(stream.pipeline)
|
||||||
|
// use this as a temporary store of buckets that are being created
|
||||||
|
const STATE = {
|
||||||
|
bucketCreationPromises: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
const CONTENT_TYPE_MAP = {
|
||||||
|
html: "text/html",
|
||||||
|
css: "text/css",
|
||||||
|
js: "application/javascript",
|
||||||
|
}
|
||||||
|
const STRING_CONTENT_TYPES = [
|
||||||
|
CONTENT_TYPE_MAP.html,
|
||||||
|
CONTENT_TYPE_MAP.css,
|
||||||
|
CONTENT_TYPE_MAP.js,
|
||||||
|
]
|
||||||
|
|
||||||
|
function publicPolicy(bucketName) {
|
||||||
|
return {
|
||||||
|
Version: "2012-10-17",
|
||||||
|
Statement: [
|
||||||
|
{
|
||||||
|
Effect: "Allow",
|
||||||
|
Principal: {
|
||||||
|
AWS: ["*"],
|
||||||
|
},
|
||||||
|
Action: "s3:GetObject",
|
||||||
|
Resource: [`arn:aws:s3:::${bucketName}/*`],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const PUBLIC_BUCKETS = [ObjectStoreBuckets.APPS, ObjectStoreBuckets.GLOBAL]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a connection to the object store using the S3 SDK.
|
||||||
|
* @param {string} bucket the name of the bucket which blobs will be uploaded/retrieved from.
|
||||||
|
* @return {Object} an S3 object store object, check S3 Nodejs SDK for usage.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
exports.ObjectStore = bucket => {
|
||||||
|
AWS.config.update({
|
||||||
|
accessKeyId: env.MINIO_ACCESS_KEY,
|
||||||
|
secretAccessKey: env.MINIO_SECRET_KEY,
|
||||||
|
})
|
||||||
|
const config = {
|
||||||
|
s3ForcePathStyle: true,
|
||||||
|
signatureVersion: "v4",
|
||||||
|
params: {
|
||||||
|
Bucket: bucket,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if (env.MINIO_URL) {
|
||||||
|
config.endpoint = env.MINIO_URL
|
||||||
|
}
|
||||||
|
return new AWS.S3(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an object store and a bucket name this will make sure the bucket exists,
|
||||||
|
* if it does not exist then it will create it.
|
||||||
|
*/
|
||||||
|
exports.makeSureBucketExists = async (client, bucketName) => {
|
||||||
|
try {
|
||||||
|
await client
|
||||||
|
.headBucket({
|
||||||
|
Bucket: bucketName,
|
||||||
|
})
|
||||||
|
.promise()
|
||||||
|
} catch (err) {
|
||||||
|
const promises = STATE.bucketCreationPromises
|
||||||
|
if (promises[bucketName]) {
|
||||||
|
await promises[bucketName]
|
||||||
|
} else if (err.statusCode === 404) {
|
||||||
|
// bucket doesn't exist create it
|
||||||
|
promises[bucketName] = client
|
||||||
|
.createBucket({
|
||||||
|
Bucket: bucketName,
|
||||||
|
})
|
||||||
|
.promise()
|
||||||
|
await promises[bucketName]
|
||||||
|
delete promises[bucketName]
|
||||||
|
// public buckets are quite hidden in the system, make sure
|
||||||
|
// no bucket is set accidentally
|
||||||
|
if (PUBLIC_BUCKETS.includes(bucketName)) {
|
||||||
|
await client
|
||||||
|
.putBucketPolicy({
|
||||||
|
Bucket: bucketName,
|
||||||
|
Policy: JSON.stringify(publicPolicy(bucketName)),
|
||||||
|
})
|
||||||
|
.promise()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads the contents of a file given the required parameters, useful when
|
||||||
|
* temp files in use (for example file uploaded as an attachment).
|
||||||
|
*/
|
||||||
|
exports.upload = async ({ bucket, filename, path, type, metadata }) => {
|
||||||
|
const extension = [...filename.split(".")].pop()
|
||||||
|
const fileBytes = fs.readFileSync(path)
|
||||||
|
|
||||||
|
const objectStore = exports.ObjectStore(bucket)
|
||||||
|
await exports.makeSureBucketExists(objectStore, bucket)
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
// windows file paths need to be converted to forward slashes for s3
|
||||||
|
Key: sanitize(filename).replace(/\\/g, "/"),
|
||||||
|
Body: fileBytes,
|
||||||
|
ContentType: type || CONTENT_TYPE_MAP[extension.toLowerCase()],
|
||||||
|
}
|
||||||
|
if (metadata) {
|
||||||
|
config.Metadata = metadata
|
||||||
|
}
|
||||||
|
return objectStore.upload(config).promise()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to the upload function but can be used to send a file stream
|
||||||
|
* through to the object store.
|
||||||
|
*/
|
||||||
|
exports.streamUpload = async (bucket, filename, stream) => {
|
||||||
|
const objectStore = exports.ObjectStore(bucket)
|
||||||
|
await exports.makeSureBucketExists(objectStore, bucket)
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Key: sanitize(filename).replace(/\\/g, "/"),
|
||||||
|
Body: stream,
|
||||||
|
}
|
||||||
|
return objectStore.upload(params).promise()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retrieves the contents of a file from the object store, if it is a known content type it
|
||||||
|
* will be converted, otherwise it will be returned as a buffer stream.
|
||||||
|
*/
|
||||||
|
exports.retrieve = async (bucket, filepath) => {
|
||||||
|
const objectStore = exports.ObjectStore(bucket)
|
||||||
|
const params = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Key: sanitize(filepath).replace(/\\/g, "/"),
|
||||||
|
}
|
||||||
|
const response = await objectStore.getObject(params).promise()
|
||||||
|
// currently these are all strings
|
||||||
|
if (STRING_CONTENT_TYPES.includes(response.ContentType)) {
|
||||||
|
return response.Body.toString("utf8")
|
||||||
|
} else {
|
||||||
|
return response.Body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as retrieval function but puts to a temporary file.
|
||||||
|
*/
|
||||||
|
exports.retrieveToTmp = async (bucket, filepath) => {
|
||||||
|
const data = await exports.retrieve(bucket, filepath)
|
||||||
|
const outputPath = join(budibaseTempDir(), v4())
|
||||||
|
fs.writeFileSync(outputPath, data)
|
||||||
|
return outputPath
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.deleteFolder = async (bucket, folder) => {
|
||||||
|
const client = exports.ObjectStore(bucket)
|
||||||
|
const listParams = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Prefix: folder,
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = await client.listObjects(listParams).promise()
|
||||||
|
if (response.Contents.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const deleteParams = {
|
||||||
|
Bucket: bucket,
|
||||||
|
Delete: {
|
||||||
|
Objects: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Contents.forEach(content => {
|
||||||
|
deleteParams.Delete.Objects.push({ Key: content.Key })
|
||||||
|
})
|
||||||
|
|
||||||
|
response = await client.deleteObjects(deleteParams).promise()
|
||||||
|
// can only empty 1000 items at once
|
||||||
|
if (response.Deleted.length === 1000) {
|
||||||
|
return exports.deleteFolder(bucket, folder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.uploadDirectory = async (bucket, localPath, bucketPath) => {
|
||||||
|
let uploads = []
|
||||||
|
const files = fs.readdirSync(localPath, { withFileTypes: true })
|
||||||
|
for (let file of files) {
|
||||||
|
const path = join(bucketPath, file.name)
|
||||||
|
const local = join(localPath, file.name)
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
uploads.push(exports.uploadDirectory(bucket, local, path))
|
||||||
|
} else {
|
||||||
|
uploads.push(
|
||||||
|
exports.streamUpload(bucket, path, fs.createReadStream(local))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await Promise.all(uploads)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.downloadTarball = async (url, bucket, path) => {
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`unexpected response ${response.statusText}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tmpPath = join(budibaseTempDir(), path)
|
||||||
|
await streamPipeline(response.body, zlib.Unzip(), tar.extract(tmpPath))
|
||||||
|
if (!env.isTest()) {
|
||||||
|
await exports.uploadDirectory(bucket, tmpPath, path)
|
||||||
|
}
|
||||||
|
// return the temporary path incase there is a use for it
|
||||||
|
return tmpPath
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
const { join } = require("path")
|
||||||
|
const { tmpdir } = require("os")
|
||||||
|
|
||||||
|
exports.ObjectStoreBuckets = {
|
||||||
|
BACKUPS: "backups",
|
||||||
|
APPS: "prod-budi-app-assets",
|
||||||
|
TEMPLATES: "templates",
|
||||||
|
GLOBAL: "global",
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.budibaseTempDir = function () {
|
||||||
|
return join(tmpdir(), ".budibase")
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
const env = require("../environment")
|
||||||
|
// ioredis mock is all in memory
|
||||||
|
const Redis = env.isTest() ? require("ioredis-mock") : require("ioredis")
|
||||||
|
const { addDbPrefix, removeDbPrefix, getRedisOptions } = require("./utils")
|
||||||
|
|
||||||
|
const CLUSTERED = false
|
||||||
|
|
||||||
|
// for testing just generate the client once
|
||||||
|
let CLIENT = env.isTest() ? new Redis(getRedisOptions()) : null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inits the system, will error if unable to connect to redis cluster (may take up to 10 seconds) otherwise
|
||||||
|
* will return the ioredis client which will be ready to use.
|
||||||
|
* @return {Promise<object>} The ioredis client.
|
||||||
|
*/
|
||||||
|
function init() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// testing uses a single in memory client
|
||||||
|
if (env.isTest()) {
|
||||||
|
return resolve(CLIENT)
|
||||||
|
}
|
||||||
|
// if a connection existed, close it and re-create it
|
||||||
|
if (CLIENT) {
|
||||||
|
CLIENT.disconnect()
|
||||||
|
CLIENT = null
|
||||||
|
}
|
||||||
|
const { opts, host, port } = getRedisOptions(CLUSTERED)
|
||||||
|
if (CLUSTERED) {
|
||||||
|
CLIENT = new Redis.Cluster([{ host, port }], opts)
|
||||||
|
} else {
|
||||||
|
CLIENT = new Redis(opts)
|
||||||
|
}
|
||||||
|
CLIENT.on("end", err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
CLIENT.on("error", err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
CLIENT.on("connect", () => {
|
||||||
|
resolve(CLIENT)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function, takes a redis stream and converts it to a promisified response -
|
||||||
|
* this can only be done with redis streams because they will have an end.
|
||||||
|
* @param stream A redis stream, specifically as this type of stream will have an end.
|
||||||
|
* @return {Promise<object>} The final output of the stream
|
||||||
|
*/
|
||||||
|
function promisifyStream(stream) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const outputKeys = new Set()
|
||||||
|
stream.on("data", keys => {
|
||||||
|
keys.forEach(key => {
|
||||||
|
outputKeys.add(key)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
stream.on("error", err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
stream.on("end", async () => {
|
||||||
|
const keysArray = Array.from(outputKeys)
|
||||||
|
try {
|
||||||
|
let getPromises = []
|
||||||
|
for (let key of keysArray) {
|
||||||
|
getPromises.push(CLIENT.get(key))
|
||||||
|
}
|
||||||
|
const jsonArray = await Promise.all(getPromises)
|
||||||
|
resolve(
|
||||||
|
keysArray.map(key => ({
|
||||||
|
key: removeDbPrefix(key),
|
||||||
|
value: JSON.parse(jsonArray.shift()),
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
class RedisWrapper {
|
||||||
|
constructor(db) {
|
||||||
|
this._db = db
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
this._client = await init()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
async finish() {
|
||||||
|
this._client.disconnect()
|
||||||
|
}
|
||||||
|
|
||||||
|
async scan() {
|
||||||
|
const db = this._db,
|
||||||
|
client = this._client
|
||||||
|
let stream
|
||||||
|
if (CLUSTERED) {
|
||||||
|
let node = client.nodes("master")
|
||||||
|
stream = node[0].scanStream({ match: db + "-*", count: 100 })
|
||||||
|
} else {
|
||||||
|
stream = client.scanStream({ match: db + "-*", count: 100 })
|
||||||
|
}
|
||||||
|
return promisifyStream(stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(key) {
|
||||||
|
const db = this._db,
|
||||||
|
client = this._client
|
||||||
|
let response = await client.get(addDbPrefix(db, key))
|
||||||
|
// overwrite the prefixed key
|
||||||
|
if (response != null && response.key) {
|
||||||
|
response.key = key
|
||||||
|
}
|
||||||
|
// if its not an object just return the response
|
||||||
|
try {
|
||||||
|
return JSON.parse(response)
|
||||||
|
} catch (err) {
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async store(key, value, expirySeconds = null) {
|
||||||
|
const db = this._db,
|
||||||
|
client = this._client
|
||||||
|
if (typeof value === "object") {
|
||||||
|
value = JSON.stringify(value)
|
||||||
|
}
|
||||||
|
const prefixedKey = addDbPrefix(db, key)
|
||||||
|
await client.set(prefixedKey, value)
|
||||||
|
if (expirySeconds) {
|
||||||
|
await client.expire(prefixedKey, expirySeconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(key) {
|
||||||
|
const db = this._db,
|
||||||
|
client = this._client
|
||||||
|
await client.del(addDbPrefix(db, key))
|
||||||
|
}
|
||||||
|
|
||||||
|
async clear() {
|
||||||
|
const db = this._db
|
||||||
|
let items = await this.scan(db)
|
||||||
|
await Promise.all(items.map(obj => this.delete(db, obj.key)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RedisWrapper
|
|
@ -0,0 +1,46 @@
|
||||||
|
const env = require("../environment")
|
||||||
|
|
||||||
|
const SLOT_REFRESH_MS = 2000
|
||||||
|
const CONNECT_TIMEOUT_MS = 10000
|
||||||
|
const SEPARATOR = "-"
|
||||||
|
const REDIS_URL = !env.REDIS_URL ? "localhost:6379" : env.REDIS_URL
|
||||||
|
const REDIS_PASSWORD = !env.REDIS_PASSWORD ? "budibase" : env.REDIS_PASSWORD
|
||||||
|
|
||||||
|
exports.Databases = {
|
||||||
|
PW_RESETS: "pwReset",
|
||||||
|
INVITATIONS: "invitation",
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.getRedisOptions = (clustered = false) => {
|
||||||
|
const [host, port] = REDIS_URL.split(":")
|
||||||
|
const opts = {
|
||||||
|
connectTimeout: CONNECT_TIMEOUT_MS,
|
||||||
|
}
|
||||||
|
if (clustered) {
|
||||||
|
opts.redisOptions = {}
|
||||||
|
opts.redisOptions.tls = {}
|
||||||
|
opts.redisOptions.password = REDIS_PASSWORD
|
||||||
|
opts.slotsRefreshTimeout = SLOT_REFRESH_MS
|
||||||
|
opts.dnsLookup = (address, callback) => callback(null, address)
|
||||||
|
} else {
|
||||||
|
opts.host = host
|
||||||
|
opts.port = port
|
||||||
|
opts.password = REDIS_PASSWORD
|
||||||
|
}
|
||||||
|
return { opts, host, port }
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.addDbPrefix = (db, key) => {
|
||||||
|
return `${db}${SEPARATOR}${key}`
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.removeDbPrefix = key => {
|
||||||
|
let parts = key.split(SEPARATOR)
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
parts.shift()
|
||||||
|
return parts.join(SEPARATOR)
|
||||||
|
} else {
|
||||||
|
// return the only part
|
||||||
|
return parts[0]
|
||||||
|
}
|
||||||
|
}
|
|
@ -105,6 +105,12 @@ exports.isClient = ctx => {
|
||||||
return ctx.headers["x-budibase-type"] === "client"
|
return ctx.headers["x-budibase-type"] === "client"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an email address this will use a view to search through
|
||||||
|
* all the users to find one with this email address.
|
||||||
|
* @param {string} email the email to lookup the user by.
|
||||||
|
* @return {Promise<object|null>}
|
||||||
|
*/
|
||||||
exports.getGlobalUserByEmail = async email => {
|
exports.getGlobalUserByEmail = async email => {
|
||||||
const db = getDB(StaticDatabases.GLOBAL.name)
|
const db = getDB(StaticDatabases.GLOBAL.name)
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -36,6 +36,21 @@ asynckit@^0.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||||
|
|
||||||
|
aws-sdk@^2.901.0:
|
||||||
|
version "2.901.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.901.0.tgz#96b387778cf2b3537383fba04994e815f1fab4d4"
|
||||||
|
integrity sha512-prmUjg4mjguamnwaXMdm/g1xtnT9515cjSaV/MhBsMUVzhe66EX7dLwiA7Jo8qUlwFMyCVIcp/2T+6KwJ9sQgQ==
|
||||||
|
dependencies:
|
||||||
|
buffer "4.9.2"
|
||||||
|
events "1.1.1"
|
||||||
|
ieee754 "1.1.13"
|
||||||
|
jmespath "0.15.0"
|
||||||
|
querystring "0.2.0"
|
||||||
|
sax "1.2.1"
|
||||||
|
url "0.10.3"
|
||||||
|
uuid "3.3.2"
|
||||||
|
xml2js "0.4.19"
|
||||||
|
|
||||||
aws-sign2@~0.7.0:
|
aws-sign2@~0.7.0:
|
||||||
version "0.7.0"
|
version "0.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||||
|
@ -46,6 +61,16 @@ aws4@^1.8.0:
|
||||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
||||||
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
||||||
|
|
||||||
|
balanced-match@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||||
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
|
base64-js@^1.0.2, base64-js@^1.3.1:
|
||||||
|
version "1.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||||
|
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||||
|
|
||||||
base64url@3.x.x:
|
base64url@3.x.x:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
|
resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
|
||||||
|
@ -63,16 +88,60 @@ bcryptjs@^2.4.3:
|
||||||
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
|
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
|
||||||
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
|
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
|
||||||
|
|
||||||
|
bl@^4.0.3:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
|
||||||
|
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
|
||||||
|
dependencies:
|
||||||
|
buffer "^5.5.0"
|
||||||
|
inherits "^2.0.4"
|
||||||
|
readable-stream "^3.4.0"
|
||||||
|
|
||||||
|
brace-expansion@^1.1.7:
|
||||||
|
version "1.1.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
|
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||||
|
dependencies:
|
||||||
|
balanced-match "^1.0.0"
|
||||||
|
concat-map "0.0.1"
|
||||||
|
|
||||||
buffer-equal-constant-time@1.0.1:
|
buffer-equal-constant-time@1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||||
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
|
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
|
||||||
|
|
||||||
|
buffer@4.9.2:
|
||||||
|
version "4.9.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
|
||||||
|
integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
|
||||||
|
dependencies:
|
||||||
|
base64-js "^1.0.2"
|
||||||
|
ieee754 "^1.1.4"
|
||||||
|
isarray "^1.0.0"
|
||||||
|
|
||||||
|
buffer@^5.5.0:
|
||||||
|
version "5.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
|
||||||
|
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
|
||||||
|
dependencies:
|
||||||
|
base64-js "^1.3.1"
|
||||||
|
ieee754 "^1.1.13"
|
||||||
|
|
||||||
caseless@~0.12.0:
|
caseless@~0.12.0:
|
||||||
version "0.12.0"
|
version "0.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||||
|
|
||||||
|
chownr@^1.1.1:
|
||||||
|
version "1.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||||
|
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
|
||||||
|
|
||||||
|
cluster-key-slot@^1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
|
||||||
|
integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==
|
||||||
|
|
||||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||||
version "1.0.8"
|
version "1.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||||
|
@ -80,6 +149,11 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
|
concat-map@0.0.1:
|
||||||
|
version "0.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
core-util-is@1.0.2:
|
core-util-is@1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||||
|
@ -92,11 +166,23 @@ dashdash@^1.12.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
assert-plus "^1.0.0"
|
assert-plus "^1.0.0"
|
||||||
|
|
||||||
|
debug@^4.3.1:
|
||||||
|
version "4.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||||
|
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
|
||||||
|
dependencies:
|
||||||
|
ms "2.1.2"
|
||||||
|
|
||||||
delayed-stream@~1.0.0:
|
delayed-stream@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||||
|
|
||||||
|
denque@^1.1.0:
|
||||||
|
version "1.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de"
|
||||||
|
integrity sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==
|
||||||
|
|
||||||
ecc-jsbn@~0.1.1:
|
ecc-jsbn@~0.1.1:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
||||||
|
@ -112,6 +198,18 @@ ecdsa-sig-formatter@1.0.11:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
|
||||||
|
version "1.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||||
|
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
|
||||||
|
dependencies:
|
||||||
|
once "^1.4.0"
|
||||||
|
|
||||||
|
events@1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
|
||||||
|
integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=
|
||||||
|
|
||||||
extend@~3.0.2:
|
extend@~3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||||
|
@ -137,6 +235,20 @@ fast-json-stable-stringify@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||||
|
|
||||||
|
fengari-interop@^0.1.2:
|
||||||
|
version "0.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/fengari-interop/-/fengari-interop-0.1.2.tgz#f7731dcdd2ff4449073fb7ac3c451a8841ce1e87"
|
||||||
|
integrity sha512-8iTvaByZVoi+lQJhHH9vC+c/Yaok9CwOqNQZN6JrVpjmWwW4dDkeblBXhnHC+BoI6eF4Cy5NKW3z6ICEjvgywQ==
|
||||||
|
|
||||||
|
fengari@^0.1.4:
|
||||||
|
version "0.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/fengari/-/fengari-0.1.4.tgz#72416693cd9e43bd7d809d7829ddc0578b78b0bb"
|
||||||
|
integrity sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==
|
||||||
|
dependencies:
|
||||||
|
readline-sync "^1.4.9"
|
||||||
|
sprintf-js "^1.1.1"
|
||||||
|
tmp "^0.0.33"
|
||||||
|
|
||||||
forever-agent@~0.6.1:
|
forever-agent@~0.6.1:
|
||||||
version "0.6.1"
|
version "0.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||||
|
@ -151,6 +263,11 @@ form-data@~2.3.2:
|
||||||
combined-stream "^1.0.6"
|
combined-stream "^1.0.6"
|
||||||
mime-types "^2.1.12"
|
mime-types "^2.1.12"
|
||||||
|
|
||||||
|
fs-constants@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||||
|
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||||
|
|
||||||
getpass@^0.1.1:
|
getpass@^0.1.1:
|
||||||
version "0.1.7"
|
version "0.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||||
|
@ -216,16 +333,68 @@ http-signature@~1.2.0:
|
||||||
jsprim "^1.2.2"
|
jsprim "^1.2.2"
|
||||||
sshpk "^1.7.0"
|
sshpk "^1.7.0"
|
||||||
|
|
||||||
|
ieee754@1.1.13:
|
||||||
|
version "1.1.13"
|
||||||
|
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
|
||||||
|
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
|
||||||
|
|
||||||
|
ieee754@^1.1.13, ieee754@^1.1.4:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||||
|
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||||
|
|
||||||
|
inherits@^2.0.3, inherits@^2.0.4:
|
||||||
|
version "2.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
|
|
||||||
|
ioredis-mock@^5.5.5:
|
||||||
|
version "5.5.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/ioredis-mock/-/ioredis-mock-5.5.5.tgz#dec9fedd238c6ab9f56c026fc366533144f8a256"
|
||||||
|
integrity sha512-7SxCAwNtDLC8IFDptqIhOC7ajp3fciVtCrXOEOkpyjPboAGRQkJbnpNPy1NYORoWi+0/iOtUPUQckSKtSQj4DA==
|
||||||
|
dependencies:
|
||||||
|
fengari "^0.1.4"
|
||||||
|
fengari-interop "^0.1.2"
|
||||||
|
lodash "^4.17.21"
|
||||||
|
minimatch "^3.0.4"
|
||||||
|
standard-as-callback "^2.1.0"
|
||||||
|
|
||||||
|
ioredis@^4.27.1:
|
||||||
|
version "4.27.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.27.1.tgz#4ef947b455a1b995baa4b0d7e2c4e4f75f746421"
|
||||||
|
integrity sha512-PaFNFeBbOcEYHXAdrJuy7uesJcyvzStTM1aYMchTuky+VgKqDbXhnTJHaDsjAwcTwPx8Asatx+l2DW8zZ2xlsQ==
|
||||||
|
dependencies:
|
||||||
|
cluster-key-slot "^1.1.0"
|
||||||
|
debug "^4.3.1"
|
||||||
|
denque "^1.1.0"
|
||||||
|
lodash.defaults "^4.2.0"
|
||||||
|
lodash.flatten "^4.4.0"
|
||||||
|
p-map "^2.1.0"
|
||||||
|
redis-commands "1.7.0"
|
||||||
|
redis-errors "^1.2.0"
|
||||||
|
redis-parser "^3.0.0"
|
||||||
|
standard-as-callback "^2.1.0"
|
||||||
|
|
||||||
is-typedarray@~1.0.0:
|
is-typedarray@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||||
|
|
||||||
|
isarray@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||||
|
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||||
|
|
||||||
isstream@~0.1.2:
|
isstream@~0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
||||||
|
|
||||||
|
jmespath@0.15.0:
|
||||||
|
version "0.15.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217"
|
||||||
|
integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=
|
||||||
|
|
||||||
jsbn@~0.1.0:
|
jsbn@~0.1.0:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||||
|
@ -296,6 +465,16 @@ koa-passport@^4.1.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
passport "^0.4.0"
|
passport "^0.4.0"
|
||||||
|
|
||||||
|
lodash.defaults@^4.2.0:
|
||||||
|
version "4.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
|
||||||
|
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
|
||||||
|
|
||||||
|
lodash.flatten@^4.4.0:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
|
||||||
|
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
|
||||||
|
|
||||||
lodash.includes@^4.3.0:
|
lodash.includes@^4.3.0:
|
||||||
version "4.3.0"
|
version "4.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
|
||||||
|
@ -336,7 +515,7 @@ lodash.once@^4.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
|
||||||
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
|
||||||
|
|
||||||
lodash@^4.14.0:
|
lodash@^4.14.0, lodash@^4.17.21:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
@ -358,11 +537,33 @@ mime@^1.4.1:
|
||||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||||
|
|
||||||
|
minimatch@^3.0.4:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||||
|
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||||
|
dependencies:
|
||||||
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
|
mkdirp-classic@^0.5.2:
|
||||||
|
version "0.5.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
|
||||||
|
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
|
||||||
|
|
||||||
|
ms@2.1.2:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
ms@^2.1.1:
|
ms@^2.1.1:
|
||||||
version "2.1.3"
|
version "2.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||||
|
|
||||||
|
node-fetch@^2.6.1:
|
||||||
|
version "2.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||||
|
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||||
|
|
||||||
node-forge@^0.7.1:
|
node-forge@^0.7.1:
|
||||||
version "0.7.6"
|
version "0.7.6"
|
||||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac"
|
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac"
|
||||||
|
@ -378,6 +579,23 @@ oauth@0.9.x:
|
||||||
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
|
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
|
||||||
integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE=
|
integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE=
|
||||||
|
|
||||||
|
once@^1.3.1, once@^1.4.0:
|
||||||
|
version "1.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||||
|
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||||
|
dependencies:
|
||||||
|
wrappy "1"
|
||||||
|
|
||||||
|
os-tmpdir@~1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||||
|
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
|
||||||
|
|
||||||
|
p-map@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
|
||||||
|
integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
|
||||||
|
|
||||||
passport-google-auth@^1.0.2:
|
passport-google-auth@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/passport-google-auth/-/passport-google-auth-1.0.2.tgz#8b300b5aa442ef433de1d832ed3112877d0b2938"
|
resolved "https://registry.yarnpkg.com/passport-google-auth/-/passport-google-auth-1.0.2.tgz#8b300b5aa442ef433de1d832ed3112877d0b2938"
|
||||||
|
@ -471,6 +689,19 @@ psl@^1.1.28:
|
||||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
||||||
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
|
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
|
||||||
|
|
||||||
|
pump@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
|
||||||
|
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
|
||||||
|
dependencies:
|
||||||
|
end-of-stream "^1.1.0"
|
||||||
|
once "^1.3.1"
|
||||||
|
|
||||||
|
punycode@1.3.2:
|
||||||
|
version "1.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
|
||||||
|
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
|
||||||
|
|
||||||
punycode@^2.1.0, punycode@^2.1.1:
|
punycode@^2.1.0, punycode@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||||
|
@ -481,6 +712,42 @@ qs@~6.5.2:
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||||
|
|
||||||
|
querystring@0.2.0:
|
||||||
|
version "0.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
|
||||||
|
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
|
||||||
|
|
||||||
|
readable-stream@^3.1.1, readable-stream@^3.4.0:
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||||
|
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||||
|
dependencies:
|
||||||
|
inherits "^2.0.3"
|
||||||
|
string_decoder "^1.1.1"
|
||||||
|
util-deprecate "^1.0.1"
|
||||||
|
|
||||||
|
readline-sync@^1.4.9:
|
||||||
|
version "1.4.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b"
|
||||||
|
integrity sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==
|
||||||
|
|
||||||
|
redis-commands@1.7.0:
|
||||||
|
version "1.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
|
||||||
|
integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
|
||||||
|
|
||||||
|
redis-errors@^1.0.0, redis-errors@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
|
||||||
|
integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=
|
||||||
|
|
||||||
|
redis-parser@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
|
||||||
|
integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=
|
||||||
|
dependencies:
|
||||||
|
redis-errors "^1.0.0"
|
||||||
|
|
||||||
request@^2.72.0, request@^2.74.0:
|
request@^2.72.0, request@^2.74.0:
|
||||||
version "2.88.2"
|
version "2.88.2"
|
||||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||||
|
@ -507,7 +774,7 @@ request@^2.72.0, request@^2.74.0:
|
||||||
tunnel-agent "^0.6.0"
|
tunnel-agent "^0.6.0"
|
||||||
uuid "^3.3.2"
|
uuid "^3.3.2"
|
||||||
|
|
||||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2:
|
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
|
||||||
version "5.2.1"
|
version "5.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||||
|
@ -517,11 +784,31 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||||
|
|
||||||
|
sanitize-s3-objectkey@^0.0.1:
|
||||||
|
version "0.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/sanitize-s3-objectkey/-/sanitize-s3-objectkey-0.0.1.tgz#efa9887cd45275b40234fb4bb12fc5754fe64e7e"
|
||||||
|
integrity sha512-ZTk7aqLxy4sD40GWcYWoLfbe05XLmkKvh6vGKe13ADlei24xlezcvjgKy1qRArlaIbIMYaqK7PCalvZtulZlaQ==
|
||||||
|
|
||||||
|
sax@1.2.1:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
|
||||||
|
integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o=
|
||||||
|
|
||||||
|
sax@>=0.6.0:
|
||||||
|
version "1.2.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||||
|
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||||
|
|
||||||
semver@^5.6.0:
|
semver@^5.6.0:
|
||||||
version "5.7.1"
|
version "5.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||||
|
|
||||||
|
sprintf-js@^1.1.1:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
|
||||||
|
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
|
||||||
|
|
||||||
sshpk@^1.7.0:
|
sshpk@^1.7.0:
|
||||||
version "1.16.1"
|
version "1.16.1"
|
||||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
|
||||||
|
@ -537,11 +824,51 @@ sshpk@^1.7.0:
|
||||||
safer-buffer "^2.0.2"
|
safer-buffer "^2.0.2"
|
||||||
tweetnacl "~0.14.0"
|
tweetnacl "~0.14.0"
|
||||||
|
|
||||||
|
standard-as-callback@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45"
|
||||||
|
integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==
|
||||||
|
|
||||||
string-template@~1.0.0:
|
string-template@~1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96"
|
resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96"
|
||||||
integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=
|
integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=
|
||||||
|
|
||||||
|
string_decoder@^1.1.1:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||||
|
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||||
|
dependencies:
|
||||||
|
safe-buffer "~5.2.0"
|
||||||
|
|
||||||
|
tar-fs@^2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
|
||||||
|
integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
|
||||||
|
dependencies:
|
||||||
|
chownr "^1.1.1"
|
||||||
|
mkdirp-classic "^0.5.2"
|
||||||
|
pump "^3.0.0"
|
||||||
|
tar-stream "^2.1.4"
|
||||||
|
|
||||||
|
tar-stream@^2.1.4:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
|
||||||
|
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
|
||||||
|
dependencies:
|
||||||
|
bl "^4.0.3"
|
||||||
|
end-of-stream "^1.4.1"
|
||||||
|
fs-constants "^1.0.0"
|
||||||
|
inherits "^2.0.3"
|
||||||
|
readable-stream "^3.1.1"
|
||||||
|
|
||||||
|
tmp@^0.0.33:
|
||||||
|
version "0.0.33"
|
||||||
|
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
|
||||||
|
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
|
||||||
|
dependencies:
|
||||||
|
os-tmpdir "~1.0.2"
|
||||||
|
|
||||||
tough-cookie@~2.5.0:
|
tough-cookie@~2.5.0:
|
||||||
version "2.5.0"
|
version "2.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||||
|
@ -574,11 +901,29 @@ uri-js@^4.2.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode "^2.1.0"
|
punycode "^2.1.0"
|
||||||
|
|
||||||
|
url@0.10.3:
|
||||||
|
version "0.10.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64"
|
||||||
|
integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=
|
||||||
|
dependencies:
|
||||||
|
punycode "1.3.2"
|
||||||
|
querystring "0.2.0"
|
||||||
|
|
||||||
|
util-deprecate@^1.0.1:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||||
|
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||||
|
|
||||||
utils-merge@1.x.x:
|
utils-merge@1.x.x:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||||
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
|
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
|
||||||
|
|
||||||
|
uuid@3.3.2:
|
||||||
|
version "3.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
|
||||||
|
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
|
||||||
|
|
||||||
uuid@^3.3.2:
|
uuid@^3.3.2:
|
||||||
version "3.4.0"
|
version "3.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||||
|
@ -597,3 +942,26 @@ verror@1.10.0:
|
||||||
assert-plus "^1.0.0"
|
assert-plus "^1.0.0"
|
||||||
core-util-is "1.0.2"
|
core-util-is "1.0.2"
|
||||||
extsprintf "^1.2.0"
|
extsprintf "^1.2.0"
|
||||||
|
|
||||||
|
wrappy@1:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||||
|
|
||||||
|
xml2js@0.4.19:
|
||||||
|
version "0.4.19"
|
||||||
|
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
|
||||||
|
integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==
|
||||||
|
dependencies:
|
||||||
|
sax ">=0.6.0"
|
||||||
|
xmlbuilder "~9.0.1"
|
||||||
|
|
||||||
|
xmlbuilder@~9.0.1:
|
||||||
|
version "9.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
|
||||||
|
integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
|
||||||
|
|
||||||
|
zlib@^1.0.5:
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/zlib/-/zlib-1.0.5.tgz#6e7c972fc371c645a6afb03ab14769def114fcc0"
|
||||||
|
integrity sha1-bnyXL8NxxkWmr7A6sUdp3vEU/MA=
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
"rollup-plugin-postcss": "^4.0.0",
|
"rollup-plugin-postcss": "^4.0.0",
|
||||||
"rollup-plugin-svelte": "^7.1.0",
|
"rollup-plugin-svelte": "^7.1.0",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"svelte": "^3.37.0"
|
"svelte": "^3.38.2"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"svelte"
|
"svelte"
|
||||||
|
|
|
@ -42,12 +42,14 @@
|
||||||
class="spectrum-ActionButton spectrum-ActionButton--size{size}"
|
class="spectrum-ActionButton spectrum-ActionButton--size{size}"
|
||||||
{disabled}
|
{disabled}
|
||||||
on:longPress
|
on:longPress
|
||||||
on:click|preventDefault>
|
on:click|preventDefault
|
||||||
|
>
|
||||||
{#if longPressable}
|
{#if longPressable}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-CornerTriangle100 spectrum-ActionButton-hold"
|
class="spectrum-Icon spectrum-UIIcon-CornerTriangle100 spectrum-ActionButton-hold"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-CornerTriangle100" />
|
<use xlink:href="#spectrum-css-icon-CornerTriangle100" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -56,7 +58,8 @@
|
||||||
class="spectrum-Icon spectrum-Icon--size{size}"
|
class="spectrum-Icon spectrum-Icon--size{size}"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
aria-label={icon}>
|
aria-label={icon}
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-{icon}" />
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// Attaches a spectrum-ActionGroup-item class to buttons inside the div
|
// Attaches a spectrum-ActionGroup-item class to buttons inside the div
|
||||||
function group(element) {
|
function group(element) {
|
||||||
const buttons = Array.from(element.getElementsByTagName("button"))
|
const buttons = Array.from(element.getElementsByTagName("button"))
|
||||||
buttons.forEach((button) => {
|
buttons.forEach(button => {
|
||||||
button.classList.add("spectrum-ActionGroup-item")
|
button.classList.add("spectrum-ActionGroup-item")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import Menu from "../Menu/Menu.svelte"
|
import Menu from "../Menu/Menu.svelte"
|
||||||
|
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
|
export let align = "left"
|
||||||
|
|
||||||
let anchor
|
let anchor
|
||||||
let dropdown
|
let dropdown
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
<div use:getAnchor on:click={openMenu}>
|
<div use:getAnchor on:click={openMenu}>
|
||||||
<slot name="control" />
|
<slot name="control" />
|
||||||
</div>
|
</div>
|
||||||
<Popover bind:this={dropdown} {anchor} align="left">
|
<Popover bind:this={dropdown} {anchor} {align}>
|
||||||
<Menu>
|
<Menu>
|
||||||
<slot />
|
<slot />
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
|
@ -1,12 +1,53 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/avatar/dist/index-vars.css"
|
import "@spectrum-css/avatar/dist/index-vars.css"
|
||||||
|
let sizes = new Map([
|
||||||
|
["XXS", "--spectrum-alias-avatar-size-50"],
|
||||||
|
["XS", "--spectrum-alias-avatar-size-75"],
|
||||||
|
["S", "--spectrum-alias-avatar-size-200"],
|
||||||
|
["M", "--spectrum-alias-avatar-size-300"],
|
||||||
|
["L", "--spectrum-alias-avatar-size-500"],
|
||||||
|
["XL", "--spectrum-alias-avatar-size-600"],
|
||||||
|
["XXL", "--spectrum-alias-avatar-size-700"],
|
||||||
|
])
|
||||||
|
export let size = "M"
|
||||||
export let url = ""
|
export let url = ""
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
|
export let name = "John Doe"
|
||||||
|
|
||||||
|
function getInitials(name) {
|
||||||
|
let parts = name.split(" ")
|
||||||
|
return parts.map(name => name[0]).join("")
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<img
|
{#if url}
|
||||||
class:is-disabled={disabled}
|
<img
|
||||||
class="spectrum-Avatar"
|
class:is-disabled={disabled}
|
||||||
src={url}
|
class="spectrum-Avatar"
|
||||||
alt="Avatar"
|
src={url}
|
||||||
/>
|
alt="Avatar"
|
||||||
|
style="width: var({sizes.get(size)}); height: var({sizes.get(size)});"
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<div
|
||||||
|
class:is-disabled={disabled}
|
||||||
|
style="width: var({sizes.get(size)}); height: var({sizes.get(
|
||||||
|
size
|
||||||
|
)}); font-size: calc(var({sizes.get(size)}) / 2)"
|
||||||
|
>
|
||||||
|
{getInitials(name)}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
color: white;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
background: #3aab87;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -23,13 +23,15 @@
|
||||||
class:active
|
class:active
|
||||||
class="spectrum-Button spectrum-Button--size{size.toUpperCase()}"
|
class="spectrum-Button spectrum-Button--size{size.toUpperCase()}"
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click|preventDefault>
|
on:click|preventDefault
|
||||||
|
>
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}"
|
class="spectrum-Icon spectrum-Icon--size{size.toUpperCase()}"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
aria-label={icon}>
|
aria-label={icon}
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-{icon}" />
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/buttongroup/dist/index-vars.css"
|
import "@spectrum-css/buttongroup/dist/index-vars.css"
|
||||||
export let vertical = false
|
export let vertical = false
|
||||||
|
|
||||||
function group(element) {
|
function group(element) {
|
||||||
const buttons = Array.from(element.getElementsByTagName('button'))
|
const buttons = Array.from(element.getElementsByTagName("button"))
|
||||||
buttons.forEach(button => {
|
buttons.forEach(button => {
|
||||||
button.classList.add('spectrum-ButtonGroup-item')
|
button.classList.add("spectrum-ButtonGroup-item")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div use:group class="spectrum-ButtonGroup" class:spectrum-ButtonGroup--vertical={vertical}>
|
<div
|
||||||
<slot />
|
use:group
|
||||||
</div>
|
class="spectrum-ButtonGroup"
|
||||||
|
class:spectrum-ButtonGroup--vertical={vertical}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
|
@ -37,8 +37,10 @@
|
||||||
<section class="drawer" transition:slide>
|
<section class="drawer" transition:slide>
|
||||||
<header>
|
<header>
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<Heading xs>{title}</Heading>
|
<Heading size="XS">{title}</Heading>
|
||||||
<Body xxs><slot name="description" /></Body>
|
<Body size="XXS">
|
||||||
|
<slot name="description" />
|
||||||
|
</Body>
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<slot name="buttons" />
|
<slot name="buttons" />
|
||||||
|
|
|
@ -28,11 +28,9 @@
|
||||||
border-right: var(--border-light);
|
border-right: var(--border-light);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar::-webkit-scrollbar {
|
.sidebar::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,5 +35,6 @@
|
||||||
{placeholder}
|
{placeholder}
|
||||||
{getOptionLabel}
|
{getOptionLabel}
|
||||||
{getOptionValue}
|
{getOptionValue}
|
||||||
on:change={onChange} />
|
on:change={onChange}
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -17,27 +17,31 @@
|
||||||
|
|
||||||
<label
|
<label
|
||||||
class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized"
|
class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized"
|
||||||
class:is-invalid={!!error}>
|
class:is-invalid={!!error}
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
checked={value}
|
checked={value}
|
||||||
{disabled}
|
{disabled}
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="spectrum-Checkbox-input"
|
class="spectrum-Checkbox-input"
|
||||||
{id} />
|
{id}
|
||||||
|
/>
|
||||||
<span class="spectrum-Checkbox-box">
|
<span class="spectrum-Checkbox-box">
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
|
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
||||||
</svg>
|
</svg>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark"
|
class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Dash100" />
|
<use xlink:href="#spectrum-css-icon-Dash100" />
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<span class="spectrum-Checkbox-label">{text || ''}</span>
|
<span class="spectrum-Checkbox-label">{text || ""}</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -51,12 +51,14 @@
|
||||||
class="spectrum-InputGroup"
|
class="spectrum-InputGroup"
|
||||||
class:is-focused={open || focus}
|
class:is-focused={open || focus}
|
||||||
class:is-invalid={!!error}
|
class:is-invalid={!!error}
|
||||||
class:is-disabled={disabled}>
|
class:is-disabled={disabled}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="spectrum-Textfield spectrum-InputGroup-textfield"
|
class="spectrum-Textfield spectrum-InputGroup-textfield"
|
||||||
class:is-invalid={!!error}
|
class:is-invalid={!!error}
|
||||||
class:is-disabled={disabled}
|
class:is-disabled={disabled}
|
||||||
class:is-focused={open || focus}>
|
class:is-focused={open || focus}
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
on:focus={() => (focus = true)}
|
on:focus={() => (focus = true)}
|
||||||
|
@ -65,18 +67,21 @@
|
||||||
{value}
|
{value}
|
||||||
{disabled}
|
{disabled}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
class="spectrum-Textfield-input spectrum-InputGroup-input" />
|
class="spectrum-Textfield-input spectrum-InputGroup-input"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="spectrum-Picker spectrum-Picker--sizeM spectrum-InputGroup-button"
|
class="spectrum-Picker spectrum-Picker--sizeM spectrum-InputGroup-button"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click={() => (open = true)}>
|
on:click={() => (open = true)}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon spectrum-InputGroup-icon"
|
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon spectrum-InputGroup-icon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Chevron100" />
|
<use xlink:href="#spectrum-css-icon-Chevron100" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
@ -84,7 +89,8 @@
|
||||||
<div class="overlay" on:mousedown|self={() => (open = false)} />
|
<div class="overlay" on:mousedown|self={() => (open = false)} />
|
||||||
<div
|
<div
|
||||||
transition:fly={{ y: -20, duration: 200 }}
|
transition:fly={{ y: -20, duration: 200 }}
|
||||||
class="spectrum-Popover spectrum-Popover--bottom is-open">
|
class="spectrum-Popover spectrum-Popover--bottom is-open"
|
||||||
|
>
|
||||||
<ul class="spectrum-Menu" role="listbox">
|
<ul class="spectrum-Menu" role="listbox">
|
||||||
{#if options && Array.isArray(options)}
|
{#if options && Array.isArray(options)}
|
||||||
{#each options as option}
|
{#each options as option}
|
||||||
|
@ -94,13 +100,16 @@
|
||||||
role="option"
|
role="option"
|
||||||
aria-selected="true"
|
aria-selected="true"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
on:click={() => selectOption(getOptionValue(option))}>
|
on:click={() => selectOption(getOptionValue(option))}
|
||||||
<span
|
>
|
||||||
class="spectrum-Menu-itemLabel">{getOptionLabel(option)}</span>
|
<span class="spectrum-Menu-itemLabel"
|
||||||
|
>{getOptionLabel(option)}</span
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
||||||
</svg>
|
</svg>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -64,7 +64,8 @@
|
||||||
on:close={onClose}
|
on:close={onClose}
|
||||||
options={flatpickrOptions}
|
options={flatpickrOptions}
|
||||||
on:change={handleChange}
|
on:change={handleChange}
|
||||||
element={`#${flatpickrId}`}>
|
element={`#${flatpickrId}`}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
id={flatpickrId}
|
id={flatpickrId}
|
||||||
class:is-disabled={disabled}
|
class:is-disabled={disabled}
|
||||||
|
@ -73,17 +74,20 @@
|
||||||
class:is-focused={open}
|
class:is-focused={open}
|
||||||
aria-readonly="false"
|
aria-readonly="false"
|
||||||
aria-required="false"
|
aria-required="false"
|
||||||
aria-haspopup="true">
|
aria-haspopup="true"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
on:click={flatpickr?.open}
|
on:click={flatpickr?.open}
|
||||||
class="spectrum-Textfield spectrum-InputGroup-textfield"
|
class="spectrum-Textfield spectrum-InputGroup-textfield"
|
||||||
class:is-disabled={disabled}
|
class:is-disabled={disabled}
|
||||||
class:is-invalid={!!error}>
|
class:is-invalid={!!error}
|
||||||
|
>
|
||||||
{#if !!error}
|
{#if !!error}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-Alert" />
|
<use xlink:href="#spectrum-icon-18-Alert" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -94,7 +98,8 @@
|
||||||
class="spectrum-Textfield-input spectrum-InputGroup-input"
|
class="spectrum-Textfield-input spectrum-InputGroup-input"
|
||||||
{placeholder}
|
{placeholder}
|
||||||
{id}
|
{id}
|
||||||
{value} />
|
{value}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -102,12 +107,14 @@
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
{disabled}
|
{disabled}
|
||||||
class:is-invalid={!!error}
|
class:is-invalid={!!error}
|
||||||
on:click={flatpickr?.open}>
|
on:click={flatpickr?.open}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--sizeM"
|
class="spectrum-Icon spectrum-Icon--sizeM"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
aria-label="Calendar">
|
aria-label="Calendar"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-Calendar" />
|
<use xlink:href="#spectrum-icon-18-Calendar" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
export let fileSizeLimit = BYTES_IN_MB * 20
|
export let fileSizeLimit = BYTES_IN_MB * 20
|
||||||
export let processFiles = null
|
export let processFiles = null
|
||||||
export let handleFileTooLarge = null
|
export let handleFileTooLarge = null
|
||||||
|
export let gallery = true
|
||||||
|
export let error = null
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const imageExtensions = [
|
const imageExtensions = [
|
||||||
|
@ -52,6 +54,8 @@
|
||||||
const newValue = [...value, ...processedFiles]
|
const newValue = [...value, ...processedFiles]
|
||||||
dispatch("change", newValue)
|
dispatch("change", newValue)
|
||||||
selectedImageIdx = newValue.length - 1
|
selectedImageIdx = newValue.length - 1
|
||||||
|
} else {
|
||||||
|
dispatch("change", fileList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,45 +98,68 @@
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
{#if selectedImage}
|
{#if selectedImage}
|
||||||
<div class="gallery">
|
{#if gallery}
|
||||||
<div class="title">
|
<div class="gallery">
|
||||||
<div class="filename">{selectedImage.name}</div>
|
<div class="title">
|
||||||
<div class="filesize">
|
<div class="filename">{selectedImage.name}</div>
|
||||||
{#if selectedImage.size <= BYTES_IN_MB}
|
<div class="filesize">
|
||||||
{`${selectedImage.size / BYTES_IN_KB} KB`}
|
{#if selectedImage.size <= BYTES_IN_MB}
|
||||||
{:else}{`${selectedImage.size / BYTES_IN_MB} MB`}{/if}
|
{`${selectedImage.size / BYTES_IN_KB} KB`}
|
||||||
|
{:else}{`${selectedImage.size / BYTES_IN_MB} MB`}{/if}
|
||||||
|
</div>
|
||||||
|
{#if !disabled}
|
||||||
|
<div class="delete-button" on:click={removeFile}>
|
||||||
|
<Icon name="Close" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if !disabled}
|
{#if isImage}
|
||||||
<div class="delete-button" on:click={removeFile}>
|
<img alt="preview" src={selectedImage.url} />
|
||||||
<Icon name="Close" />
|
{:else}
|
||||||
|
<div class="placeholder">
|
||||||
|
<div class="extension">{selectedImage.extension}</div>
|
||||||
|
<div>Preview not supported</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
<div
|
||||||
{#if isImage}
|
class="nav left"
|
||||||
<img alt="preview" src={selectedImage.url} />
|
class:visible={selectedImageIdx > 0}
|
||||||
{:else}
|
on:click={navigateLeft}
|
||||||
<div class="placeholder">
|
>
|
||||||
<div class="extension">{selectedImage.extension}</div>
|
<Icon name="ChevronLeft" />
|
||||||
<div>Preview not supported</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
<div
|
||||||
<div
|
class="nav right"
|
||||||
class="nav left"
|
class:visible={selectedImageIdx < fileCount - 1}
|
||||||
class:visible={selectedImageIdx > 0}
|
on:click={navigateRight}
|
||||||
on:click={navigateLeft}>
|
>
|
||||||
<Icon name="ChevronLeft" />
|
<Icon name="ChevronRight" />
|
||||||
|
</div>
|
||||||
|
<div class="footer">File {selectedImageIdx + 1} of {fileCount}</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
{:else if value?.length}
|
||||||
class="nav right"
|
{#each value as file}
|
||||||
class:visible={selectedImageIdx < fileCount - 1}
|
<div class="gallery">
|
||||||
on:click={navigateRight}>
|
<div class="title">
|
||||||
<Icon name="ChevronRight" />
|
<div class="filename">{file.name}</div>
|
||||||
</div>
|
<div class="filesize">
|
||||||
<div class="footer">File {selectedImageIdx + 1} of {fileCount}</div>
|
{#if file.size <= BYTES_IN_MB}
|
||||||
</div>
|
{`${file.size / BYTES_IN_KB} KB`}
|
||||||
|
{:else}{`${file.size / BYTES_IN_MB} MB`}{/if}
|
||||||
|
</div>
|
||||||
|
{#if !disabled}
|
||||||
|
<div class="delete-button" on:click={removeFile}>
|
||||||
|
<Icon name="Close" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
<div
|
<div
|
||||||
class="spectrum-Dropzone"
|
class="spectrum-Dropzone"
|
||||||
|
class:is-invalid={!!error}
|
||||||
class:disabled
|
class:disabled
|
||||||
role="region"
|
role="region"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
|
@ -140,19 +167,22 @@
|
||||||
on:dragleave={handleDragLeave}
|
on:dragleave={handleDragLeave}
|
||||||
on:dragenter={handleDragOver}
|
on:dragenter={handleDragOver}
|
||||||
on:drop={handleDrop}
|
on:drop={handleDrop}
|
||||||
class:is-dragged={fileDragged}>
|
class:is-dragged={fileDragged}
|
||||||
|
>
|
||||||
<div class="spectrum-IllustratedMessage spectrum-IllustratedMessage--cta">
|
<div class="spectrum-IllustratedMessage spectrum-IllustratedMessage--cta">
|
||||||
<input
|
<input
|
||||||
id={fieldId}
|
id={fieldId}
|
||||||
{disabled}
|
{disabled}
|
||||||
type="file"
|
type="file"
|
||||||
multiple
|
multiple
|
||||||
on:change={handleFile} />
|
on:change={handleFile}
|
||||||
|
/>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-IllustratedMessage-illustration"
|
class="spectrum-IllustratedMessage-illustration"
|
||||||
width="125"
|
width="125"
|
||||||
height="60"
|
height="60"
|
||||||
viewBox="0 0 199 97.7"><defs>
|
viewBox="0 0 199 97.7"
|
||||||
|
><defs>
|
||||||
<style>
|
<style>
|
||||||
.cls-1,
|
.cls-1,
|
||||||
.cls-2 {
|
.cls-2 {
|
||||||
|
@ -170,25 +200,31 @@
|
||||||
</defs>
|
</defs>
|
||||||
<path
|
<path
|
||||||
class="cls-1"
|
class="cls-1"
|
||||||
d="M110.53,85.66,100.26,95.89a1.09,1.09,0,0,1-1.52,0L88.47,85.66" />
|
d="M110.53,85.66,100.26,95.89a1.09,1.09,0,0,1-1.52,0L88.47,85.66"
|
||||||
|
/>
|
||||||
<line class="cls-1" x1="99.5" y1="95.5" x2="99.5" y2="58.5" />
|
<line class="cls-1" x1="99.5" y1="95.5" x2="99.5" y2="58.5" />
|
||||||
<path class="cls-1" d="M105.5,73.5h19a2,2,0,0,0,2-2v-43" />
|
<path class="cls-1" d="M105.5,73.5h19a2,2,0,0,0,2-2v-43" />
|
||||||
<path
|
<path
|
||||||
class="cls-1"
|
class="cls-1"
|
||||||
d="M126.5,22.5h-19a2,2,0,0,1-2-2V1.5h-31a2,2,0,0,0-2,2v68a2,2,0,0,0,2,2h19" />
|
d="M126.5,22.5h-19a2,2,0,0,1-2-2V1.5h-31a2,2,0,0,0-2,2v68a2,2,0,0,0,2,2h19"
|
||||||
|
/>
|
||||||
<line class="cls-1" x1="105.5" y1="1.5" x2="126.5" y2="22.5" />
|
<line class="cls-1" x1="105.5" y1="1.5" x2="126.5" y2="22.5" />
|
||||||
<path
|
<path
|
||||||
class="cls-2"
|
class="cls-2"
|
||||||
d="M47.93,50.49a5,5,0,1,0-4.83-5A4.93,4.93,0,0,0,47.93,50.49Z" />
|
d="M47.93,50.49a5,5,0,1,0-4.83-5A4.93,4.93,0,0,0,47.93,50.49Z"
|
||||||
|
/>
|
||||||
<path
|
<path
|
||||||
class="cls-2"
|
class="cls-2"
|
||||||
d="M36.6,65.93,42.05,60A2.06,2.06,0,0,1,45,60l12.68,13.2" />
|
d="M36.6,65.93,42.05,60A2.06,2.06,0,0,1,45,60l12.68,13.2"
|
||||||
|
/>
|
||||||
<path
|
<path
|
||||||
class="cls-2"
|
class="cls-2"
|
||||||
d="M3.14,73.23,22.42,53.76a1.65,1.65,0,0,1,2.38,0l19.05,19.7" />
|
d="M3.14,73.23,22.42,53.76a1.65,1.65,0,0,1,2.38,0l19.05,19.7"
|
||||||
|
/>
|
||||||
<path
|
<path
|
||||||
class="cls-1"
|
class="cls-1"
|
||||||
d="M139.5,36.5H196A1.49,1.49,0,0,1,197.5,38V72A1.49,1.49,0,0,1,196,73.5H141A1.49,1.49,0,0,1,139.5,72V32A1.49,1.49,0,0,1,141,30.5H154a2.43,2.43,0,0,1,1.67.66l6,5.66" />
|
d="M139.5,36.5H196A1.49,1.49,0,0,1,197.5,38V72A1.49,1.49,0,0,1,196,73.5H141A1.49,1.49,0,0,1,139.5,72V32A1.49,1.49,0,0,1,141,30.5H154a2.43,2.43,0,0,1,1.67.66l6,5.66"
|
||||||
|
/>
|
||||||
<rect
|
<rect
|
||||||
class="cls-1"
|
class="cls-1"
|
||||||
x="1.5"
|
x="1.5"
|
||||||
|
@ -196,16 +232,21 @@
|
||||||
width="58"
|
width="58"
|
||||||
height="39"
|
height="39"
|
||||||
rx="2"
|
rx="2"
|
||||||
ry="2" />
|
ry="2"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<h2
|
<h2
|
||||||
class="spectrum-Heading spectrum-Heading--sizeL spectrum-Heading--light spectrum-IllustratedMessage-heading">
|
class="spectrum-Heading spectrum-Heading--sizeL spectrum-Heading--light spectrum-IllustratedMessage-heading"
|
||||||
|
>
|
||||||
Drag and drop your file
|
Drag and drop your file
|
||||||
</h2>
|
</h2>
|
||||||
{#if !disabled}
|
{#if !disabled}
|
||||||
<p
|
<p
|
||||||
class="spectrum-Body spectrum-Body--sizeS spectrum-IllustratedMessage-description">
|
class="spectrum-Body spectrum-Body--sizeS spectrum-IllustratedMessage-description"
|
||||||
<label for={fieldId} class="spectrum-Link">Select a file to upload</label>
|
>
|
||||||
|
<label for={fieldId} class="spectrum-Link"
|
||||||
|
>Select a file to upload</label
|
||||||
|
>
|
||||||
<br />
|
<br />
|
||||||
from your computer
|
from your computer
|
||||||
</p>
|
</p>
|
||||||
|
@ -229,6 +270,9 @@
|
||||||
.spectrum-Dropzone {
|
.spectrum-Dropzone {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
.spectrum-Dropzone.is-invalid {
|
||||||
|
border-color: var(--spectrum-global-color-red-400);
|
||||||
|
}
|
||||||
input[type="file"] {
|
input[type="file"] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +304,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.filename {
|
.filename {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
@ -315,6 +359,7 @@
|
||||||
.delete-button {
|
.delete-button {
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
.delete-button i {
|
.delete-button i {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
|
|
|
@ -78,4 +78,5 @@
|
||||||
{isOptionSelected}
|
{isOptionSelected}
|
||||||
{getOptionLabel}
|
{getOptionLabel}
|
||||||
{getOptionValue}
|
{getOptionValue}
|
||||||
onSelectOption={toggleOption} />
|
onSelectOption={toggleOption}
|
||||||
|
/>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
export let getOptionValue = option => option
|
export let getOptionValue = option => option
|
||||||
export let open = false
|
export let open = false
|
||||||
export let readonly = false
|
export let readonly = false
|
||||||
|
export let quiet = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const onClick = e => {
|
const onClick = e => {
|
||||||
|
@ -33,11 +34,13 @@
|
||||||
<button
|
<button
|
||||||
{id}
|
{id}
|
||||||
class="spectrum-Picker spectrum-Picker--sizeM"
|
class="spectrum-Picker spectrum-Picker--sizeM"
|
||||||
|
class:spectrum-Picker--quiet={quiet}
|
||||||
{disabled}
|
{disabled}
|
||||||
class:is-invalid={!!error}
|
class:is-invalid={!!error}
|
||||||
class:is-open={open}
|
class:is-open={open}
|
||||||
aria-haspopup="listbox"
|
aria-haspopup="listbox"
|
||||||
on:mousedown={onClick}>
|
on:mousedown={onClick}
|
||||||
|
>
|
||||||
<span class="spectrum-Picker-label" class:is-placeholder={isPlaceholder}>
|
<span class="spectrum-Picker-label" class:is-placeholder={isPlaceholder}>
|
||||||
{fieldText}
|
{fieldText}
|
||||||
</span>
|
</span>
|
||||||
|
@ -46,14 +49,16 @@
|
||||||
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Picker-validationIcon"
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Picker-validationIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
aria-label="Folder">
|
aria-label="Folder"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-Alert" />
|
<use xlink:href="#spectrum-icon-18-Alert" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
|
class="spectrum-Icon spectrum-UIIcon-ChevronDown100 spectrum-Picker-menuIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Chevron100" />
|
<use xlink:href="#spectrum-css-icon-Chevron100" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
@ -61,7 +66,8 @@
|
||||||
<div
|
<div
|
||||||
use:clickOutside={() => (open = false)}
|
use:clickOutside={() => (open = false)}
|
||||||
transition:fly={{ y: -20, duration: 200 }}
|
transition:fly={{ y: -20, duration: 200 }}
|
||||||
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open">
|
class="spectrum-Popover spectrum-Popover--bottom spectrum-Picker-popover is-open"
|
||||||
|
>
|
||||||
<ul class="spectrum-Menu" role="listbox">
|
<ul class="spectrum-Menu" role="listbox">
|
||||||
{#if placeholderOption}
|
{#if placeholderOption}
|
||||||
<li
|
<li
|
||||||
|
@ -70,12 +76,14 @@
|
||||||
role="option"
|
role="option"
|
||||||
aria-selected="true"
|
aria-selected="true"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
on:click={() => onSelectOption(null)}>
|
on:click={() => onSelectOption(null)}
|
||||||
|
>
|
||||||
<span class="spectrum-Menu-itemLabel">{placeholderOption}</span>
|
<span class="spectrum-Menu-itemLabel">{placeholderOption}</span>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
||||||
</svg>
|
</svg>
|
||||||
</li>
|
</li>
|
||||||
|
@ -88,13 +96,16 @@
|
||||||
role="option"
|
role="option"
|
||||||
aria-selected="true"
|
aria-selected="true"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
on:click={() => onSelectOption(getOptionValue(option, idx))}>
|
on:click={() => onSelectOption(getOptionValue(option, idx))}
|
||||||
<span
|
>
|
||||||
class="spectrum-Menu-itemLabel">{getOptionLabel(option, idx)}</span>
|
<span class="spectrum-Menu-itemLabel"
|
||||||
|
>{getOptionLabel(option, idx)}</span
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Menu-checkmark spectrum-Menu-itemIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
||||||
</svg>
|
</svg>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -21,14 +21,16 @@
|
||||||
<div
|
<div
|
||||||
title={getOptionLabel(option)}
|
title={getOptionLabel(option)}
|
||||||
class="spectrum-Radio spectrum-FieldGroup-item spectrum-Radio--emphasized"
|
class="spectrum-Radio spectrum-FieldGroup-item spectrum-Radio--emphasized"
|
||||||
class:is-invalid={!!error}>
|
class:is-invalid={!!error}
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
bind:group={value}
|
bind:group={value}
|
||||||
value={getOptionValue(option)}
|
value={getOptionValue(option)}
|
||||||
type="radio"
|
type="radio"
|
||||||
class="spectrum-Radio-input"
|
class="spectrum-Radio-input"
|
||||||
{disabled} />
|
{disabled}
|
||||||
|
/>
|
||||||
<span class="spectrum-Radio-button" />
|
<span class="spectrum-Radio-button" />
|
||||||
<label class="spectrum-Radio-label">{getOptionLabel(option)}</label>
|
<label class="spectrum-Radio-label">{getOptionLabel(option)}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,11 +34,13 @@
|
||||||
<div
|
<div
|
||||||
class="spectrum-Textfield"
|
class="spectrum-Textfield"
|
||||||
class:is-focused={focus}
|
class:is-focused={focus}
|
||||||
class:is-disabled={disabled}>
|
class:is-disabled={disabled}
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-icon"
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-icon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-Magnify" />
|
<use xlink:href="#spectrum-icon-18-Magnify" />
|
||||||
</svg>
|
</svg>
|
||||||
<input
|
<input
|
||||||
|
@ -46,23 +48,26 @@
|
||||||
on:keyup={updateValueOnEnter}
|
on:keyup={updateValueOnEnter}
|
||||||
{disabled}
|
{disabled}
|
||||||
{id}
|
{id}
|
||||||
value={value || ''}
|
value={value || ""}
|
||||||
placeholder={placeholder || ''}
|
placeholder={placeholder || ""}
|
||||||
on:blur={onBlur}
|
on:blur={onBlur}
|
||||||
on:focus={onFocus}
|
on:focus={onFocus}
|
||||||
on:input
|
on:input
|
||||||
type="search"
|
type="search"
|
||||||
class="spectrum-Textfield-input spectrum-Search-input"
|
class="spectrum-Textfield-input spectrum-Search-input"
|
||||||
autocomplete="off" />
|
autocomplete="off"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
on:click={() => updateValue('')}
|
on:click={() => updateValue("")}
|
||||||
type="reset"
|
type="reset"
|
||||||
class="spectrum-ClearButton spectrum-Search-clearButton">
|
class="spectrum-ClearButton spectrum-Search-clearButton"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-Cross75"
|
class="spectrum-Icon spectrum-UIIcon-Cross75"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Cross75" />
|
<use xlink:href="#spectrum-css-icon-Cross75" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
export let getOptionLabel = option => option
|
export let getOptionLabel = option => option
|
||||||
export let getOptionValue = option => option
|
export let getOptionValue = option => option
|
||||||
export let readonly = false
|
export let readonly = false
|
||||||
|
export let quiet = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
let open = false
|
let open = false
|
||||||
|
@ -43,6 +44,7 @@
|
||||||
<Picker
|
<Picker
|
||||||
on:click
|
on:click
|
||||||
bind:open
|
bind:open
|
||||||
|
{quiet}
|
||||||
{id}
|
{id}
|
||||||
{error}
|
{error}
|
||||||
{disabled}
|
{disabled}
|
||||||
|
@ -51,7 +53,8 @@
|
||||||
{options}
|
{options}
|
||||||
{getOptionLabel}
|
{getOptionLabel}
|
||||||
{getOptionValue}
|
{getOptionValue}
|
||||||
isPlaceholder={value == null || value === ''}
|
isPlaceholder={value == null || value === ""}
|
||||||
placeholderOption={placeholder}
|
placeholderOption={placeholder}
|
||||||
isOptionSelected={option => option === value}
|
isOptionSelected={option => option === value}
|
||||||
onSelectOption={selectOption} />
|
onSelectOption={selectOption}
|
||||||
|
/>
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
{id}
|
{id}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="spectrum-Switch-input" />
|
class="spectrum-Switch-input"
|
||||||
|
/>
|
||||||
<span class="spectrum-Switch-switch" />
|
<span class="spectrum-Switch-switch" />
|
||||||
<label class="spectrum-Switch-label" for={id}>{text}</label>
|
<label class="spectrum-Switch-label" for={id}>{text}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -25,23 +25,28 @@
|
||||||
class="spectrum-Textfield spectrum-Textfield--multiline"
|
class="spectrum-Textfield spectrum-Textfield--multiline"
|
||||||
class:is-invalid={!!error}
|
class:is-invalid={!!error}
|
||||||
class:is-disabled={disabled}
|
class:is-disabled={disabled}
|
||||||
class:is-focused={focus}>
|
class:is-focused={focus}
|
||||||
|
>
|
||||||
{#if error}
|
{#if error}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
|
class="spectrum-Icon spectrum-Icon--sizeM
|
||||||
|
spectrum-Textfield-validationIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-Alert" />
|
<use xlink:href="#spectrum-icon-18-Alert" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
<!-- prettier-ignore -->
|
||||||
<textarea
|
<textarea
|
||||||
bind:this={textarea}
|
bind:this={textarea}
|
||||||
placeholder={placeholder || ''}
|
placeholder={placeholder || ""}
|
||||||
class="spectrum-Textfield-input"
|
class="spectrum-Textfield-input"
|
||||||
{disabled}
|
{disabled}
|
||||||
{id}
|
{id}
|
||||||
on:focus={() => (focus = true)}
|
on:focus={() => (focus = true)}
|
||||||
on:blur={onChange}>{value || ''}</textarea>
|
on:blur={onChange}
|
||||||
|
>{value || ""}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
}
|
}
|
||||||
focus = false
|
focus = false
|
||||||
updateValue(event.target.value)
|
updateValue(event.target.value)
|
||||||
|
dispatch("blur")
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateValueOnEnter = event => {
|
const updateValueOnEnter = event => {
|
||||||
|
@ -53,12 +54,14 @@
|
||||||
class="spectrum-Textfield"
|
class="spectrum-Textfield"
|
||||||
class:is-invalid={!!error}
|
class:is-invalid={!!error}
|
||||||
class:is-disabled={disabled}
|
class:is-disabled={disabled}
|
||||||
class:is-focused={focus}>
|
class:is-focused={focus}
|
||||||
|
>
|
||||||
{#if error}
|
{#if error}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Textfield-validationIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-Alert" />
|
<use xlink:href="#spectrum-icon-18-Alert" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -68,13 +71,14 @@
|
||||||
{disabled}
|
{disabled}
|
||||||
{readonly}
|
{readonly}
|
||||||
{id}
|
{id}
|
||||||
value={value || ''}
|
value={value || ""}
|
||||||
placeholder={placeholder || ''}
|
placeholder={placeholder || ""}
|
||||||
on:blur={onBlur}
|
on:blur={onBlur}
|
||||||
on:focus={onFocus}
|
on:focus={onFocus}
|
||||||
on:input
|
on:input
|
||||||
{type}
|
{type}
|
||||||
class="spectrum-Textfield-input" />
|
class="spectrum-Textfield-input"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -25,5 +25,6 @@
|
||||||
{value}
|
{value}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
{enableTime}
|
{enableTime}
|
||||||
on:change={onChange} />
|
on:change={onChange}
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
export let fileSizeLimit = undefined
|
export let fileSizeLimit = undefined
|
||||||
export let processFiles = undefined
|
export let processFiles = undefined
|
||||||
export let handleFileTooLarge = undefined
|
export let handleFileTooLarge = undefined
|
||||||
|
export let gallery = true
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const onChange = e => {
|
const onChange = e => {
|
||||||
|
@ -27,5 +28,7 @@
|
||||||
{fileSizeLimit}
|
{fileSizeLimit}
|
||||||
{processFiles}
|
{processFiles}
|
||||||
{handleFileTooLarge}
|
{handleFileTooLarge}
|
||||||
on:change={onChange} />
|
{gallery}
|
||||||
|
on:change={onChange}
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
export let error = null
|
export let error = null
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="spectrum-Form-item" class:above={labelPosition === 'above'}>
|
<div class="spectrum-Form-item" class:above={labelPosition === "above"}>
|
||||||
{#if label}
|
{#if label}
|
||||||
<FieldLabel forId={id} {label} position={labelPosition} />
|
<FieldLabel forId={id} {label} position={labelPosition} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
|
|
||||||
<label
|
<label
|
||||||
for={forId}
|
for={forId}
|
||||||
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel ${className}`}>
|
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel ${className}`}
|
||||||
{label || ''}
|
>
|
||||||
|
{label || ""}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -29,5 +29,7 @@
|
||||||
{type}
|
{type}
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
on:click
|
on:click
|
||||||
on:input />
|
on:input
|
||||||
|
on:blur
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -31,5 +31,6 @@
|
||||||
{getOptionLabel}
|
{getOptionLabel}
|
||||||
{getOptionValue}
|
{getOptionValue}
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
on:click />
|
on:click
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -33,5 +33,6 @@
|
||||||
{options}
|
{options}
|
||||||
{getOptionLabel}
|
{getOptionLabel}
|
||||||
{getOptionValue}
|
{getOptionValue}
|
||||||
on:change={onChange} />
|
on:change={onChange}
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -23,5 +23,6 @@
|
||||||
{placeholder}
|
{placeholder}
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
on:click
|
on:click
|
||||||
on:input />
|
on:input
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
export let options = []
|
export let options = []
|
||||||
export let getOptionLabel = option => extractProperty(option, "label")
|
export let getOptionLabel = option => extractProperty(option, "label")
|
||||||
export let getOptionValue = option => extractProperty(option, "value")
|
export let getOptionValue = option => extractProperty(option, "value")
|
||||||
|
export let quiet = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const onChange = e => {
|
const onChange = e => {
|
||||||
|
@ -29,6 +30,7 @@
|
||||||
|
|
||||||
<Field {label} {labelPosition} {error}>
|
<Field {label} {labelPosition} {error}>
|
||||||
<Select
|
<Select
|
||||||
|
{quiet}
|
||||||
{error}
|
{error}
|
||||||
{disabled}
|
{disabled}
|
||||||
{readonly}
|
{readonly}
|
||||||
|
@ -38,5 +40,6 @@
|
||||||
{getOptionLabel}
|
{getOptionLabel}
|
||||||
{getOptionValue}
|
{getOptionValue}
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
on:click />
|
on:click
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -25,5 +25,6 @@
|
||||||
{disabled}
|
{disabled}
|
||||||
{value}
|
{value}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
on:change={onChange} />
|
on:change={onChange}
|
||||||
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/fieldlabel/dist/index-vars.css"
|
import "@spectrum-css/fieldlabel/dist/index-vars.css"
|
||||||
|
|
||||||
|
export let size = "M"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label
|
<label class={`spectrum-FieldLabel spectrum-FieldLabel--size${size}`}>
|
||||||
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeL spectrum-Form-itemLabel`}>
|
|
||||||
<slot />
|
<slot />
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
label {
|
label {
|
||||||
|
padding: 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -5,9 +5,11 @@
|
||||||
export let noPadding = false
|
export let noPadding = false
|
||||||
export let gap = "M"
|
export let gap = "M"
|
||||||
export let noGap = false
|
export let noGap = false
|
||||||
|
export let alignContent = "normal"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
style="align-content:{alignContent};"
|
||||||
class:horizontal
|
class:horizontal
|
||||||
class="container paddingX-{!noPadding && paddingX} paddingY-{!noPadding &&
|
class="container paddingX-{!noPadding && paddingX} paddingY-{!noPadding &&
|
||||||
paddingY} gap-{!noGap && gap}"
|
paddingY} gap-{!noGap && gap}"
|
||||||
|
@ -44,6 +46,9 @@
|
||||||
padding-top: var(--spacing-l);
|
padding-top: var(--spacing-l);
|
||||||
padding-bottom: var(--spacing-l);
|
padding-bottom: var(--spacing-l);
|
||||||
}
|
}
|
||||||
|
.gap-XS {
|
||||||
|
grid-gap: var(--spacing-s);
|
||||||
|
}
|
||||||
.gap-S {
|
.gap-S {
|
||||||
grid-gap: var(--spectrum-alias-grid-gutter-xsmall);
|
grid-gap: var(--spectrum-alias-grid-gutter-xsmall);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script>
|
||||||
|
export let wide = false
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class:wide>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
max-width: 80ch;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: calc(var(--spacing-xl) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wide {
|
||||||
|
max-width: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: var(--spacing-xl) calc(var(--spacing-xl) * 2)
|
||||||
|
calc(var(--spacing-xl) * 2) calc(var(--spacing-xl) * 2);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -17,4 +17,5 @@
|
||||||
class:spectrum-Link--secondary={secondary}
|
class:spectrum-Link--secondary={secondary}
|
||||||
class:spectrum-Link--overBackground={overBackground}
|
class:spectrum-Link--overBackground={overBackground}
|
||||||
class:spectrum-Link--quiet={quiet}
|
class:spectrum-Link--quiet={quiet}
|
||||||
class="spectrum-Link spectrum-Link--size{size}"><slot /></a>
|
class="spectrum-Link spectrum-Link--size{size}"><slot /></a
|
||||||
|
>
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
>
|
>
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Menu-itemIcon"
|
class="spectrum-Icon spectrum-Icon--sizeS spectrum-Menu-itemIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
aria-label={icon}
|
aria-label={icon}
|
||||||
|
@ -37,3 +37,9 @@
|
||||||
{/if}
|
{/if}
|
||||||
<span class="spectrum-Menu-itemLabel"><slot /></span>
|
<span class="spectrum-Menu-itemLabel"><slot /></span>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.spectrum-Menu-itemIcon {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/menu/dist/index-vars.css"
|
import "@spectrum-css/menu/dist/index-vars.css"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ul class="spectrum-Menu" role="menu">
|
<ul class="spectrum-Menu" role="menu">
|
||||||
<slot />
|
<slot />
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
export let heading
|
export let heading
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<li role="presentation">
|
<li role="presentation">
|
||||||
<span class="spectrum-Menu-sectionHeading">{heading}</span>
|
<span class="spectrum-Menu-sectionHeading">{heading}</span>
|
||||||
<ul class="spectrum-Menu" role="group">
|
<ul class="spectrum-Menu" role="group">
|
||||||
<slot />
|
<slot />
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<li class="spectrum-Menu-divider" role="separator"></li>
|
<li class="spectrum-Menu-divider" role="separator" />
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<div on:click={increment}>
|
<div on:click={increment}>
|
||||||
Click me
|
Click me
|
||||||
{remaining}
|
{remaining}
|
||||||
more time{remaining === 1 ? '' : 's'}
|
more time{remaining === 1 ? "" : "s"}
|
||||||
to close this modal!
|
to close this modal!
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,10 @@
|
||||||
import Context from "../context"
|
import Context from "../context"
|
||||||
|
|
||||||
export let fixed = false
|
export let fixed = false
|
||||||
|
export let inline = false
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
let visible = !!fixed
|
let visible = fixed || inline
|
||||||
$: dispatch(visible ? "show" : "hide")
|
$: dispatch(visible ? "show" : "hide")
|
||||||
|
|
||||||
export function show() {
|
export function show() {
|
||||||
|
@ -20,7 +21,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hide() {
|
export function hide() {
|
||||||
if (!visible || fixed) {
|
if (!visible || fixed || inline) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
visible = false
|
visible = false
|
||||||
|
@ -45,18 +46,26 @@
|
||||||
|
|
||||||
<svelte:window on:keydown={handleKey} />
|
<svelte:window on:keydown={handleKey} />
|
||||||
|
|
||||||
{#if visible}
|
<!-- These svelte if statements need to be defined like this. -->
|
||||||
|
<!-- The modal transitions do not work if nested inside more than one "if" -->
|
||||||
|
{#if visible && inline}
|
||||||
|
<div use:focusFirstInput class="spectrum-Modal inline is-open">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
{:else if visible}
|
||||||
<Portal target=".modal-container">
|
<Portal target=".modal-container">
|
||||||
<div
|
<div
|
||||||
class="spectrum-Underlay is-open"
|
class="spectrum-Underlay is-open"
|
||||||
transition:fade={{ duration: 200 }}
|
transition:fade|local={{ duration: 200 }}
|
||||||
on:mousedown|self={hide}>
|
on:mousedown|self={hide}
|
||||||
|
>
|
||||||
<div class="modal-wrapper" on:mousedown|self={hide}>
|
<div class="modal-wrapper" on:mousedown|self={hide}>
|
||||||
<div class="modal-inner-wrapper" on:mousedown|self={hide}>
|
<div class="modal-inner-wrapper" on:mousedown|self={hide}>
|
||||||
<div
|
<div
|
||||||
use:focusFirstInput
|
use:focusFirstInput
|
||||||
class="spectrum-Modal is-open"
|
class="spectrum-Modal is-open"
|
||||||
transition:fly={{ y: 30, duration: 200 }}>
|
transition:fly|local={{ y: 30, duration: 200 }}
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -96,6 +105,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.spectrum-Modal {
|
.spectrum-Modal {
|
||||||
|
background: var(--background);
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
max-height: none;
|
max-height: none;
|
||||||
margin: 40px 0;
|
margin: 40px 0;
|
||||||
|
@ -104,4 +114,7 @@
|
||||||
--spectrum-global-dimension-size-100
|
--spectrum-global-dimension-size-100
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
:global(.spectrum--lightest .spectrum-Modal.inline) {
|
||||||
|
border: var(--border-light);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import Context from "../context"
|
import Context from "../context"
|
||||||
|
|
||||||
export let title = undefined
|
export let title = undefined
|
||||||
export let size = "small"
|
export let size = "S"
|
||||||
export let cancelText = "Cancel"
|
export let cancelText = "Cancel"
|
||||||
export let confirmText = "Confirm"
|
export let confirmText = "Confirm"
|
||||||
export let showCancelButton = true
|
export let showCancelButton = true
|
||||||
|
@ -30,11 +30,16 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="spectrum-Dialog spectrum-Dialog--{size}"
|
class="spectrum-Dialog"
|
||||||
|
class:spectrum-Dialog--small={size === "S"}
|
||||||
|
class:spectrum-Dialog--medium={size === "M"}
|
||||||
|
class:spectrum-Dialog--large={size === "L"}
|
||||||
|
class:spectrum-Dialog--extraLarge={size === "XL"}
|
||||||
style="position: relative;"
|
style="position: relative;"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-modal="true">
|
aria-modal="true"
|
||||||
|
>
|
||||||
<div class="spectrum-Dialog-grid">
|
<div class="spectrum-Dialog-grid">
|
||||||
<h1 class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader">
|
<h1 class="spectrum-Dialog-heading spectrum-Dialog-heading--noHeader">
|
||||||
{title}
|
{title}
|
||||||
|
@ -47,7 +52,8 @@
|
||||||
</section>
|
</section>
|
||||||
{#if showCancelButton || showConfirmButton}
|
{#if showCancelButton || showConfirmButton}
|
||||||
<div
|
<div
|
||||||
class="spectrum-ButtonGroup spectrum-Dialog-buttonGroup spectrum-Dialog-buttonGroup--noFooter">
|
class="spectrum-ButtonGroup spectrum-Dialog-buttonGroup spectrum-Dialog-buttonGroup--noFooter"
|
||||||
|
>
|
||||||
<slot name="footer" />
|
<slot name="footer" />
|
||||||
{#if showCancelButton}
|
{#if showCancelButton}
|
||||||
<Button group secondary on:click={hide}>{cancelText}</Button>
|
<Button group secondary on:click={hide}>{cancelText}</Button>
|
||||||
|
@ -58,7 +64,8 @@
|
||||||
cta
|
cta
|
||||||
{...$$restProps}
|
{...$$restProps}
|
||||||
disabled={confirmDisabled}
|
disabled={confirmDisabled}
|
||||||
on:click={confirm}>
|
on:click={confirm}
|
||||||
|
>
|
||||||
{confirmText}
|
{confirmText}
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -73,6 +80,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.spectrum-Dialog--extraLarge {
|
||||||
|
width: 1000px;
|
||||||
|
}
|
||||||
|
|
||||||
.content-grid {
|
.content-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -31,7 +31,8 @@
|
||||||
bind:this={modal}
|
bind:this={modal}
|
||||||
confirmText="Submit"
|
confirmText="Submit"
|
||||||
onConfirm={answerQuiz}
|
onConfirm={answerQuiz}
|
||||||
on:show={resetState}>
|
on:show={resetState}
|
||||||
|
>
|
||||||
{#if error}
|
{#if error}
|
||||||
<p class="error">Wrong answer! Try again.</p>
|
<p class="error">Wrong answer! Try again.</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,17 +1,25 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/toast/dist/index-vars.css"
|
import "@spectrum-css/toast/dist/index-vars.css"
|
||||||
import Portal from "svelte-portal"
|
import Portal from "svelte-portal"
|
||||||
import { flip } from "svelte/animate"
|
import { flip } from "svelte/animate"
|
||||||
import { fly } from "svelte/transition"
|
import { fly } from "svelte/transition"
|
||||||
import { notifications } from '../Stores/notifications'
|
import { notifications } from "../Stores/notifications"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Portal target=".modal-container">
|
<Portal target=".modal-container">
|
||||||
<div class="notifications">
|
<div class="notifications">
|
||||||
{#each $notifications as {type, icon, message, id} (id)}
|
{#each $notifications as { type, icon, message, id } (id)}
|
||||||
<div animate:flip transition:fly={{ y: -30 }} class="spectrum-Toast spectrum-Toast--{type} notification-offset">
|
<div
|
||||||
|
animate:flip
|
||||||
|
transition:fly={{ y: -30 }}
|
||||||
|
class="spectrum-Toast spectrum-Toast--{type} notification-offset"
|
||||||
|
>
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<svg class="spectrum-Icon spectrum-Icon--sizeM spectrum-Toast-typeIcon" focusable="false" aria-hidden="true">
|
<svg
|
||||||
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-Toast-typeIcon"
|
||||||
|
focusable="false"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-{icon}" />
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -21,24 +29,24 @@
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</Portal>
|
</Portal>
|
||||||
<style>
|
|
||||||
.notifications {
|
<style>
|
||||||
position: fixed;
|
.notifications {
|
||||||
top: 10px;
|
position: fixed;
|
||||||
left: 0;
|
top: 10px;
|
||||||
right: 0;
|
left: 0;
|
||||||
margin: 0 auto;
|
right: 0;
|
||||||
padding: 0;
|
margin: 0 auto;
|
||||||
z-index: 9999;
|
padding: 0;
|
||||||
display: flex;
|
z-index: 9999;
|
||||||
flex-direction: column;
|
display: flex;
|
||||||
justify-content: flex-start;
|
flex-direction: column;
|
||||||
align-items: center;
|
justify-content: flex-start;
|
||||||
pointer-events: none;
|
align-items: center;
|
||||||
}
|
pointer-events: none;
|
||||||
.notification-offset {
|
}
|
||||||
margin-bottom: 10px;
|
.notification-offset {
|
||||||
}
|
margin-bottom: 10px;
|
||||||
</style>
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -37,7 +37,8 @@
|
||||||
use:clickOutside={hide}
|
use:clickOutside={hide}
|
||||||
on:keydown={handleEscape}
|
on:keydown={handleEscape}
|
||||||
class="spectrum-Popover is-open"
|
class="spectrum-Popover is-open"
|
||||||
role="presentation">
|
role="presentation"
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</Portal>
|
</Portal>
|
||||||
|
|
|
@ -33,22 +33,14 @@
|
||||||
>
|
>
|
||||||
{#if $$slots}
|
{#if $$slots}
|
||||||
<div
|
<div
|
||||||
class:spectrum-FieldLabel--sizeS={s}
|
class="spectrum-FieldLabel spectrum-ProgressBar-label spectrum-FieldLabel--size{size}"
|
||||||
class:spectrum-FieldLabel--sizeM={m}
|
|
||||||
class:spectrum-FieldLabel--sizeL={l}
|
|
||||||
class:spectrum-FieldLabel--sizeXL={xl}
|
|
||||||
class="spectrum-FieldLabel spectrum-ProgressBar-label"
|
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if value}
|
{#if value}
|
||||||
<div
|
<div
|
||||||
class:spectrum-FieldLabel--sizeS={s}
|
class="spectrum-FieldLabel spectrum-ProgressBar-percentage spectrum-FieldLabel--size{size}"
|
||||||
class:spectrum-FieldLabel--sizeM={m}
|
|
||||||
class:spectrum-FieldLabel--sizeL={l}
|
|
||||||
class:spectrum-FieldLabel--sizeXL={xl}
|
|
||||||
class="spectrum-FieldLabel spectrum-ProgressBar-percentage"
|
|
||||||
>
|
>
|
||||||
{Math.round($progress)}%
|
{Math.round($progress)}%
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,29 +1,62 @@
|
||||||
<script>
|
<script>
|
||||||
// WIP! Does not yet work.
|
import "@spectrum-css/progresscircle/dist/index-vars.css"
|
||||||
import "@spectrum-css/progresscircle/dist/index-vars.css"
|
|
||||||
import { tweened } from 'svelte/motion';
|
|
||||||
import { cubicOut } from 'svelte/easing';
|
|
||||||
|
|
||||||
export let value = false
|
export let size = "M"
|
||||||
export let small;
|
function convertSize(size) {
|
||||||
export let large;
|
switch (size) {
|
||||||
|
case "S":
|
||||||
|
return "small"
|
||||||
|
case "L":
|
||||||
|
return "large"
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export let overBackground;
|
export let value = false
|
||||||
|
export let minValue = 0
|
||||||
|
export let maxValue = 100
|
||||||
|
|
||||||
|
let subMask1Style
|
||||||
|
let subMask2Style
|
||||||
|
$: calculateSubMasks(value)
|
||||||
|
|
||||||
|
function calculateSubMasks(value) {
|
||||||
|
if (value) {
|
||||||
|
let percentage = ((value - minValue) / (maxValue - minValue)) * 100
|
||||||
|
let angle
|
||||||
|
if (percentage > 0 && percentage <= 50) {
|
||||||
|
angle = -180 + (percentage / 50) * 180
|
||||||
|
subMask1Style = `transform: rotate(${angle}deg);`
|
||||||
|
subMask2Style = "transform: rotate(-180deg);"
|
||||||
|
} else if (percentage > 50) {
|
||||||
|
angle = -180 + ((percentage - 50) / 50) * 180
|
||||||
|
subMask1Style = "transform: rotate(0deg);"
|
||||||
|
subMask2Style = `transform: rotate(${angle}deg);`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export let overBackground
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class:spectrum-ProgressBar--indeterminate={!value} class:spectrum-ProgressCircle--small={small} class:spectrum-ProgressCircle--large={large} class="spectrum-ProgressCircle">
|
<div
|
||||||
<div class="spectrum-ProgressCircle-track"></div>
|
on:click
|
||||||
<div class="spectrum-ProgressCircle-fills">
|
class:spectrum-ProgressBar--indeterminate={!value}
|
||||||
<div class="spectrum-ProgressCircle-fillMask1">
|
class:spectrum-ProgressCircle--overBackground={overBackground}
|
||||||
<div class="spectrum-ProgressCircle-fillSubMask1">
|
class="spectrum-ProgressCircle spectrum-ProgressCircle--{convertSize(size)}"
|
||||||
<div class="spectrum-ProgressCircle-fill"></div>
|
>
|
||||||
</div>
|
<div class="spectrum-ProgressCircle-track" />
|
||||||
|
<div class="spectrum-ProgressCircle-fills">
|
||||||
|
<div class="spectrum-ProgressCircle-fillMask1">
|
||||||
|
<div class="spectrum-ProgressCircle-fillSubMask1" style={subMask1Style}>
|
||||||
|
<div class="spectrum-ProgressCircle-fill" />
|
||||||
</div>
|
</div>
|
||||||
<div class="spectrum-ProgressCircle-fillMask2">
|
</div>
|
||||||
<div class="spectrum-ProgressCircle-fillSubMask2">
|
<div class="spectrum-ProgressCircle-fillMask2">
|
||||||
<div class="spectrum-ProgressCircle-fill"></div>
|
<div class="spectrum-ProgressCircle-fillSubMask2" style={subMask2Style}>
|
||||||
</div>
|
<div class="spectrum-ProgressCircle-fill" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -1,30 +1,44 @@
|
||||||
<script>
|
<script>
|
||||||
import { getContext } from 'svelte'
|
import { getContext } from "svelte"
|
||||||
const multilevel = getContext('sidenav-type');
|
const multilevel = getContext("sidenav-type")
|
||||||
export let href = "";
|
export let href = ""
|
||||||
export let external = false;
|
export let external = false
|
||||||
export let heading = ""
|
export let heading = ""
|
||||||
export let icon = "";
|
export let icon = ""
|
||||||
export let selected = false;
|
export let selected = false
|
||||||
export let disabled = false;
|
export let disabled = false
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<li class="spectrum-SideNav-item" class:is-selected={selected} class:is-disabled={disabled}>
|
<li
|
||||||
{#if heading}
|
class="spectrum-SideNav-item"
|
||||||
<h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}">{heading}</h2>
|
class:is-selected={selected}
|
||||||
|
class:is-disabled={disabled}
|
||||||
|
>
|
||||||
|
{#if heading}
|
||||||
|
<h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}">
|
||||||
|
{heading}
|
||||||
|
</h2>
|
||||||
|
{/if}
|
||||||
|
<a
|
||||||
|
target={external ? "_blank" : ""}
|
||||||
|
{href}
|
||||||
|
class="spectrum-SideNav-itemLink"
|
||||||
|
aria-current="page"
|
||||||
|
>
|
||||||
|
{#if icon}
|
||||||
|
<svg
|
||||||
|
class="spectrum-Icon spectrum-Icon--sizeM spectrum-SideNav-itemIcon"
|
||||||
|
focusable="false"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
<a target={external ? '_blank' : '_self'} {href} class="spectrum-SideNav-itemLink" aria-current="page">
|
<slot />
|
||||||
{#if icon}
|
</a>
|
||||||
<svg class="spectrum-Icon spectrum-Icon--sizeM spectrum-SideNav-itemIcon" focusable="false" aria-hidden="true">
|
{#if multilevel && $$slots.subnav}
|
||||||
<use xlink:href="#spectrum-icon-18-{icon}" />
|
<ul class="spectrum-SideNav">
|
||||||
</svg>
|
<slot name="subnav" />
|
||||||
{/if}
|
</ul>
|
||||||
<slot />
|
{/if}
|
||||||
</a>
|
</li>
|
||||||
{#if multilevel && $$slots.subnav}
|
|
||||||
<ul class="spectrum-SideNav">
|
|
||||||
<slot name="subnav" />
|
|
||||||
</ul>
|
|
||||||
{/if}
|
|
||||||
</li>
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { setContext } from 'svelte'
|
import { setContext } from "svelte"
|
||||||
import "@spectrum-css/sidenav/dist/index-vars.css"
|
import "@spectrum-css/sidenav/dist/index-vars.css"
|
||||||
export let multilevel = false;
|
export let multilevel = false
|
||||||
setContext('sidenav-type', multilevel)
|
setContext("sidenav-type", multilevel)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<ul class="spectrum-SideNav" class:spectrum-SideNav--multiLevel={multilevel}>
|
<ul class="spectrum-SideNav" class:spectrum-SideNav--multiLevel={multilevel}>
|
||||||
<slot />
|
<slot />
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -50,12 +50,7 @@ export const createNotificationStore = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function id() {
|
function id() {
|
||||||
return (
|
return "_" + Math.random().toString(36).substr(2, 9)
|
||||||
"_" +
|
|
||||||
Math.random()
|
|
||||||
.toString(36)
|
|
||||||
.substr(2, 9)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const notifications = createNotificationStore()
|
export const notifications = createNotificationStore()
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
<script>
|
|
||||||
export let extraSmall = false,
|
|
||||||
small = false,
|
|
||||||
medium = false,
|
|
||||||
large = false,
|
|
||||||
extraLarge = false,
|
|
||||||
white = false,
|
|
||||||
grey = false,
|
|
||||||
black = false,
|
|
||||||
lh = false
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<p
|
|
||||||
class="bb-body"
|
|
||||||
class:extraSmall
|
|
||||||
class:small
|
|
||||||
class:medium
|
|
||||||
class:large
|
|
||||||
class:extraLarge
|
|
||||||
class:white
|
|
||||||
class:grey
|
|
||||||
class:black
|
|
||||||
class:lh>
|
|
||||||
<slot />
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.bb-body {
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
font-weight: 400;
|
|
||||||
text-rendering: var(--text-render);
|
|
||||||
color: var(--ink);
|
|
||||||
font-size: var(--font-size-m);
|
|
||||||
line-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.extraSmall {
|
|
||||||
font-size: var(--font-size-xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
.small {
|
|
||||||
font-size: var(--font-size-s);
|
|
||||||
}
|
|
||||||
|
|
||||||
.medium {
|
|
||||||
font-size: var(--font-size-m);
|
|
||||||
}
|
|
||||||
|
|
||||||
.large {
|
|
||||||
font-size: var(--font-size-l);
|
|
||||||
}
|
|
||||||
|
|
||||||
.extraLarge {
|
|
||||||
font-size: var(--font-size-xl);
|
|
||||||
}
|
|
||||||
|
|
||||||
.white {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey {
|
|
||||||
color: var(--grey-6);
|
|
||||||
}
|
|
||||||
|
|
||||||
.black {
|
|
||||||
color: var(--ink);
|
|
||||||
}
|
|
||||||
|
|
||||||
.lh {
|
|
||||||
line-height: 1.75;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,175 +0,0 @@
|
||||||
<script>
|
|
||||||
import { View } from "svench";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<h1>Borders</h1>
|
|
||||||
<p>Budibase has 2 border variables, light and dark.</p>
|
|
||||||
<p><strong>Light</strong> is for layouts.</p>
|
|
||||||
<p><strong>Dark</strong> is for components.</p>
|
|
||||||
<code>border: var(--border-light);</code>
|
|
||||||
<div class="border-light"></div>
|
|
||||||
<code>border: var(--border-dark);</code>
|
|
||||||
<div class="border-dark"></div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h2>Border Radius</h2>
|
|
||||||
<p>Budibase has 5 border-radius variables:</p>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Var</th>
|
|
||||||
<th>rem</th>
|
|
||||||
<th>px</th>
|
|
||||||
<th>Visual</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Extra Small</td>
|
|
||||||
<td>var(--border-radius-xs)</td>
|
|
||||||
<td>0.125</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td><div class="border-radius-xs">Extra small</div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Small</td>
|
|
||||||
<td>var(--border-radius-s)</td>
|
|
||||||
<td>0.35</td>
|
|
||||||
<td>5.6px</td>
|
|
||||||
<td><div class="border-radius-s">Small</div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Medium</td>
|
|
||||||
<td>var(--border-radius-m)</td>
|
|
||||||
<td>0.5</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td><div class="border-radius-m">Medium</div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Large</td>
|
|
||||||
<td>var(--border-radius-l)</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td><div class="border-radius-l">Large</div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Extra Large</td>
|
|
||||||
<td>var(--border-radius-xl)</td>
|
|
||||||
<td>100</td>
|
|
||||||
<td>1600</td>
|
|
||||||
<td><div class="border-radius-xl">Extra large</div></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
table {
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
border-collapse: collapse;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
display: inline-block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: var(--spacing-s) var(--spacing-l);
|
|
||||||
margin: var(--spacing-xl) 0 var(--spacing-s) 0;
|
|
||||||
background-color: var(--grey-2);
|
|
||||||
color: var(--red-dark);
|
|
||||||
border-radius: var(--spacing-xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
td, th {
|
|
||||||
border: 1px solid var(--grey-4);
|
|
||||||
text-align: left;
|
|
||||||
padding: var(--spacing-m);
|
|
||||||
width: 20%;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:nth-child(even) {
|
|
||||||
background-color: var(--grey-3);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
margin: var(--layout-xl) 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-light {
|
|
||||||
width: 40rem;
|
|
||||||
height: 10rem;
|
|
||||||
background-color: white;
|
|
||||||
border: var(--border-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-dark {
|
|
||||||
width: 40rem;
|
|
||||||
height: 10rem;
|
|
||||||
background-color: white;
|
|
||||||
border: var(--border-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-radius-xs {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: white;
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
width: 8rem;
|
|
||||||
height: 3rem;
|
|
||||||
background-color: black;
|
|
||||||
border-radius: var(--border-radius-xs);
|
|
||||||
margin-right: var(--spacing-l);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-radius-s {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: white;
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
width: 8rem;
|
|
||||||
height: 3rem;
|
|
||||||
background-color: black;
|
|
||||||
border-radius: var(--border-radius-s);
|
|
||||||
margin-right: var(--spacing-l);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-radius-m {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: white;
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
width: 8rem;
|
|
||||||
height: 3rem;
|
|
||||||
background-color: black;
|
|
||||||
border-radius: var(--border-radius-m);
|
|
||||||
margin-right: var(--spacing-l);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-radius-l {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: white;
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
width: 8rem;
|
|
||||||
height: 3rem;
|
|
||||||
background-color: black;
|
|
||||||
border-radius: var(--border-radius-l);
|
|
||||||
margin-right: var(--spacing-l);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-radius-xl {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: white;
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
width: 8rem;
|
|
||||||
height: 3rem;
|
|
||||||
background-color: black;
|
|
||||||
border-radius: var(--border-radius-xl);
|
|
||||||
margin-right: var(--spacing-l);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,68 +0,0 @@
|
||||||
<svg
|
|
||||||
version="1.1"
|
|
||||||
id="Layer_1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
x="0px"
|
|
||||||
y="0px"
|
|
||||||
viewBox="0 0 115 40"
|
|
||||||
style="enable-background:new 0 0 115 40;"
|
|
||||||
xml:space="preserve">
|
|
||||||
<path
|
|
||||||
class="st0"
|
|
||||||
d="M111.16,40H3.91c-2.15,0-3.89-1.74-3.89-3.89V4.04c0-2.15,1.74-3.89,3.89-3.89h107.25
|
|
||||||
c2.15,0,3.89,1.74,3.89,3.89v32.07C115.05,38.26,113.31,40,111.16,40z" />
|
|
||||||
<path
|
|
||||||
class="st1"
|
|
||||||
d="M10.37,10.03v8.57c0.93-1.26,2.33-1.67,3.61-1.67c1.58,0,3.01,0.59,4.02,1.54c1.12,1.05,1.82,2.62,1.82,4.53
|
|
||||||
c0,1.78-0.62,3.42-1.82,4.61c-1.01,1.03-2.26,1.57-3.97,1.57c-2.05,0-3.09-0.95-3.66-1.78v1.39H6.63V10.03H10.37z
|
|
||||||
M10.97,20.98
|
|
||||||
c-0.44,0.46-0.82,1.13-0.82,2.11c0,0.95,0.41,1.64,0.85,2.05c0.59,0.57,1.41,0.85,2.11,0.85c0.64,0,1.36-0.26,1.93-0.8
|
|
||||||
c0.54-0.51,0.9-1.26,0.9-2.11c0-0.92-0.36-1.67-0.9-2.18c-0.59-0.57-1.23-0.77-1.98-0.77C12.26,20.14,11.56,20.37,10.97,20.98z" />
|
|
||||||
<path
|
|
||||||
class="st1"
|
|
||||||
d="M25.08,17.35v6.32c0,0.51,0.05,1.31,0.64,1.85c0.26,0.23,0.72,0.54,1.54,0.54c0.69,0,1.23-0.23,1.56-0.54
|
|
||||||
c0.54-0.51,0.62-1.28,0.62-1.85v-6.32h3.74v6.68c0,1.31-0.13,2.54-1.28,3.67c-1.31,1.28-3.23,1.49-4.59,1.49
|
|
||||||
c-1.41,0-3.31-0.21-4.62-1.49c-1.05-1.03-1.26-2.18-1.26-3.44v-6.91H25.08z" />
|
|
||||||
<path
|
|
||||||
class="st1"
|
|
||||||
d="M47.88,28.79h-3.74V27.4c-0.57,0.82-1.61,1.78-3.66,1.78c-1.71,0-2.96-0.54-3.97-1.57
|
|
||||||
c-1.19-1.18-1.82-2.83-1.82-4.61c0-1.9,0.7-3.47,1.82-4.53c1.01-0.95,2.44-1.54,4.02-1.54c1.27,0,2.67,0.41,3.61,1.67v-8.57h3.74
|
|
||||||
V28.79z
|
|
||||||
M39.53,20.91c-0.54,0.51-0.9,1.26-0.9,2.18c0,0.85,0.36,1.59,0.9,2.11c0.57,0.54,1.28,0.8,1.93,0.8
|
|
||||||
c0.69,0,1.52-0.28,2.11-0.85c0.44-0.41,0.85-1.1,0.85-2.05c0-0.98-0.39-1.64-0.82-2.11c-0.59-0.62-1.28-0.85-2.08-0.85
|
|
||||||
C40.77,20.14,40.12,20.34,39.53,20.91z" />
|
|
||||||
<path
|
|
||||||
class="st1"
|
|
||||||
d="M52.32,10.3c1.21,0,2.16,0.95,2.16,2.16c0,1.21-0.95,2.16-2.16,2.16c-1.21,0-2.16-0.95-2.16-2.16
|
|
||||||
C50.17,11.25,51.12,10.3,52.32,10.3z M54.19,17.35v11.44h-3.74V17.35H54.19z" />
|
|
||||||
<path
|
|
||||||
class="st1"
|
|
||||||
d="M60.49,10.03v8.57c0.93-1.26,2.33-1.67,3.61-1.67c1.58,0,3.01,0.59,4.02,1.54c1.12,1.05,1.82,2.62,1.82,4.53
|
|
||||||
c0,1.78-0.62,3.42-1.82,4.61c-1.01,1.03-2.26,1.57-3.97,1.57c-2.05,0-3.09-0.95-3.66-1.78v1.39h-3.74V10.03H60.49z
|
|
||||||
M61.06,20.98
|
|
||||||
c-0.44,0.46-0.82,1.13-0.82,2.11c0,0.95,0.41,1.64,0.85,2.05c0.59,0.57,1.41,0.85,2.11,0.85c0.64,0,1.36-0.26,1.93-0.8
|
|
||||||
c0.54-0.51,0.9-1.26,0.9-2.11c0-0.92-0.36-1.67-0.9-2.18c-0.59-0.57-1.23-0.77-1.98-0.77C62.34,20.14,61.65,20.37,61.06,20.98z" />
|
|
||||||
<path
|
|
||||||
class="st1"
|
|
||||||
d="M80.26,17.35H84v11.44h-3.74v-1.39c-1.01,1.54-2.46,1.77-3.42,1.77c-1.66,0-3.06-0.41-4.33-1.74
|
|
||||||
c-1.22-1.28-1.69-2.77-1.69-4.28c0-1.92,0.73-3.57,1.79-4.62c1.01-1,2.41-1.56,4.02-1.56c0.99,0,2.57,0.23,3.63,1.67V17.35z
|
|
||||||
M75.57,20.96c-0.39,0.39-0.85,1.05-0.85,2.08c0,1.03,0.44,1.7,0.77,2.05c0.51,0.54,1.31,0.9,2.18,0.9c0.74,0,1.44-0.31,1.93-0.8
|
|
||||||
c0.49-0.46,0.9-1.18,0.9-2.16c0-0.82-0.31-1.59-0.85-2.11c-0.57-0.54-1.39-0.8-2.05-0.8C76.8,20.14,76.06,20.47,75.57,20.96z" />
|
|
||||||
<path
|
|
||||||
class="st1"
|
|
||||||
d="M93.21,20.26c-0.57-0.33-1.31-0.64-2.03-0.64c-0.39,0-0.82,0.1-1.05,0.33c-0.13,0.13-0.23,0.33-0.23,0.51
|
|
||||||
c0,0.26,0.18,0.41,0.36,0.51c0.26,0.15,0.64,0.23,1.1,0.39l0.98,0.31c0.64,0.21,1.31,0.46,1.9,1c0.67,0.62,0.9,1.31,0.9,2.18
|
|
||||||
c0,1.52-0.67,2.49-1.18,3.01c-1.13,1.13-2.52,1.31-3.72,1.31c-1.54,0-3.21-0.33-4.7-1.64l1.57-2.49c0.36,0.31,0.87,0.67,1.26,0.85
|
|
||||||
c0.51,0.26,1.05,0.36,1.54,0.36c0.23,0,0.82,0,1.16-0.26c0.23-0.18,0.39-0.46,0.39-0.74c0-0.21-0.08-0.46-0.41-0.67
|
|
||||||
c-0.26-0.15-0.59-0.26-1.13-0.41l-0.92-0.28c-0.67-0.21-1.36-0.57-1.85-1.05c-0.54-0.57-0.82-1.21-0.82-2.08
|
|
||||||
c0-1.1,0.44-2.03,1.1-2.65c1.03-0.95,2.41-1.16,3.47-1.16c1.7,0,2.88,0.44,3.8,0.98L93.21,20.26z" />
|
|
||||||
<path
|
|
||||||
class="st1"
|
|
||||||
d="M108.43,23.73h-8.55c0,0.62,0.23,1.44,0.69,1.95c0.57,0.62,1.34,0.72,1.9,0.72c0.54,0,1.1-0.1,1.49-0.33
|
|
||||||
c0.05-0.03,0.49-0.31,0.8-0.95l3.49,0.36c-0.51,1.62-1.54,2.47-2.21,2.88c-1.1,0.67-2.34,0.85-3.62,0.85
|
|
||||||
c-1.72,0-3.24-0.31-4.57-1.64c-1-1-1.72-2.52-1.72-4.42c0-1.64,0.59-3.34,1.75-4.52c1.39-1.39,3.11-1.64,4.39-1.64
|
|
||||||
c1.28,0,3.13,0.23,4.55,1.72c1.36,1.44,1.62,3.24,1.62,4.65V23.73z
|
|
||||||
M105.03,21.48c-0.03-0.1-0.21-0.82-0.74-1.34
|
|
||||||
c-0.41-0.39-1-0.64-1.75-0.64c-0.95,0-1.52,0.39-1.87,0.74c-0.28,0.31-0.54,0.72-0.64,1.23H105.03z" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.2 KiB |
|
@ -1,201 +0,0 @@
|
||||||
<script>
|
|
||||||
import { View } from "svench";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<View name="Base">
|
|
||||||
<div class="white">white</div>
|
|
||||||
<div class="grey1">var(--grey-1)</div>
|
|
||||||
<div class="grey2">var(--grey-2)</div>
|
|
||||||
<div class="grey3">var(--grey-3)</div>
|
|
||||||
<div class="grey4">var(--grey-4)</div>
|
|
||||||
<div class="grey5">var(--grey-5)</div>
|
|
||||||
<div class="grey6">var(--grey-6)</div>
|
|
||||||
<div class="grey7">var(--grey-7)</div>
|
|
||||||
<div class="grey8">var(--grey-8)</div>
|
|
||||||
<div class="grey9">var(--grey-9)</div>
|
|
||||||
<div class="ink">var(--ink)</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="Blue">
|
|
||||||
<div class="blue-light">var(--blue-light)</div>
|
|
||||||
<div class="blue">var(--blue)</div>
|
|
||||||
<div class="blue-dark">var(--blue-dark)</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="Yellow">
|
|
||||||
<div class="yellow-light">var(--yellow-light)</div>
|
|
||||||
<div class="yellow">var(--yellow)</div>
|
|
||||||
<div class="yellow-dark">var(--yellow-dark)</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="Red">
|
|
||||||
<div class="red-light">var(--red-light)</div>
|
|
||||||
<div class="red">var(--red)</div>
|
|
||||||
<div class="red-dark">var(--red-dark)</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="Orange">
|
|
||||||
<div class="orange-light">var(--orange-light)</div>
|
|
||||||
<div class="orange">var(--orange)</div>
|
|
||||||
<div class="orange-dark">var(--orange-dark)</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="Green">
|
|
||||||
<div class="green-light">var(--green-light)</div>
|
|
||||||
<div class="green">var(--green)</div>
|
|
||||||
<div class="green-dark">var(--green-dark)</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="Purple">
|
|
||||||
<div class="purple-light">var(--purple-light)</div>
|
|
||||||
<div class="purple">var(--purple)</div>
|
|
||||||
<div class="purple-dark">var(--purple-dark)</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div {
|
|
||||||
height: 100px;
|
|
||||||
width: 800px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
}
|
|
||||||
|
|
||||||
.white {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey1 {
|
|
||||||
background-color: var(--grey-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey1 {
|
|
||||||
background-color: var(--grey-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey2 {
|
|
||||||
background-color: var(--grey-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey3 {
|
|
||||||
background-color: var(--grey-3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey4 {
|
|
||||||
background-color: var(--grey-4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey5 {
|
|
||||||
background-color: var(--grey-5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey6 {
|
|
||||||
background-color: var(--grey-6);
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey7 {
|
|
||||||
background-color: var(--grey-7);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey8 {
|
|
||||||
background-color: var(--grey-8);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey9 {
|
|
||||||
background-color: var(--grey-9);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ink {
|
|
||||||
background-color: var(--ink);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blue {
|
|
||||||
background-color: var(--blue);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blue-light {
|
|
||||||
background-color: var(--blue-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.blue-dark {
|
|
||||||
background-color: var(--blue-dark);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.yellow {
|
|
||||||
background-color: var(--yellow);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.yellow-light {
|
|
||||||
background-color: var(--yellow-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.yellow-dark {
|
|
||||||
background-color: var(--yellow-dark);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.red {
|
|
||||||
background-color: var(--red);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.red-light {
|
|
||||||
background-color: var(--red-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.red-dark {
|
|
||||||
background-color: var(--red-dark);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.orange {
|
|
||||||
background-color: var(--orange);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.orange-light {
|
|
||||||
background-color: var(--orange-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.orange-dark {
|
|
||||||
background-color: var(--orange-dark);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.green {
|
|
||||||
background-color: var(--green);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.green-light {
|
|
||||||
background-color: var(--green-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.green-dark {
|
|
||||||
background-color: var(--green-dark);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purple {
|
|
||||||
background-color: var(--purple);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purple-light {
|
|
||||||
background-color: var(--purple-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.purple-dark {
|
|
||||||
background-color: var(--purple-dark);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,74 +0,0 @@
|
||||||
<script>
|
|
||||||
export let extraSmall = false,
|
|
||||||
small = false,
|
|
||||||
medium = false,
|
|
||||||
large = false,
|
|
||||||
extraLarge = false,
|
|
||||||
white = false,
|
|
||||||
grey = false,
|
|
||||||
black = false,
|
|
||||||
lh = false
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<h1
|
|
||||||
class="bb-heading"
|
|
||||||
class:extraSmall
|
|
||||||
class:small
|
|
||||||
class:medium
|
|
||||||
class:large
|
|
||||||
class:extraLarge
|
|
||||||
class:white
|
|
||||||
class:grey
|
|
||||||
class:black
|
|
||||||
class:lh>
|
|
||||||
<slot />
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.bb-heading {
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
font-weight: 600;
|
|
||||||
text-rendering: var(--text-render);
|
|
||||||
color: var(--ink);
|
|
||||||
font-size: var(--heading-font-size-m);
|
|
||||||
line-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.extraSmall {
|
|
||||||
font-size: var(--heading-font-size-xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
.small {
|
|
||||||
font-size: var(--heading-font-size-s);
|
|
||||||
}
|
|
||||||
|
|
||||||
.medium {
|
|
||||||
font-size: var(--heading-font-size-m);
|
|
||||||
}
|
|
||||||
|
|
||||||
.large {
|
|
||||||
font-size: var(--heading-font-size-l);
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.extraLarge {
|
|
||||||
font-size: var(--heading-font-size-xl);
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.white {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grey {
|
|
||||||
color: var(--grey-6);
|
|
||||||
}
|
|
||||||
|
|
||||||
.black {
|
|
||||||
color: var(--ink);
|
|
||||||
}
|
|
||||||
|
|
||||||
.lh {
|
|
||||||
line-height: 1.3;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<script>
|
|
||||||
import BudibaseLogo from "./Budibase-logo.svelte"
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="home-logo">
|
|
||||||
<BudibaseLogo />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.home-logo {
|
|
||||||
cursor: pointer;
|
|
||||||
height: 40px;
|
|
||||||
width: 100px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<script>
|
|
||||||
import { View } from "svench";
|
|
||||||
import Logo from "./Logo.svelte";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<View name="default">
|
|
||||||
<Logo />
|
|
||||||
</View>
|
|
|
@ -1,191 +0,0 @@
|
||||||
<script>
|
|
||||||
import { View } from "svench";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<h1>2 Scales, 1 Spatial System</h1>
|
|
||||||
<p>Budibase has 2 scales, spacing and layout, and follows a 4pt grid system.</p>
|
|
||||||
<p><strong>Spacing</strong> is used for smaller, more refined spacing needs, specifically within the context of a component.</p>
|
|
||||||
<p><strong>Layout</strong> is used for laying out your page and positing components within that page.</p>
|
|
||||||
<p>Spacing and layout will mostly exist alongside margin and padding.</p>
|
|
||||||
<p><code>margin: var(--spacing-s);</code></p>
|
|
||||||
<code>padding: var(--spacing-s) var(--spacing-l);</code>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h2>Spacing</h2>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Var</th>
|
|
||||||
<th>rem</th>
|
|
||||||
<th>px</th>
|
|
||||||
<th>Visual</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--spacing-xs)</td>
|
|
||||||
<td>0.25</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td><div class="xs"></div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--spacing-s)</td>
|
|
||||||
<td>0.5</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td><div class="s"></div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--spacing-m)</td>
|
|
||||||
<td>.75</td>
|
|
||||||
<td>12</td>
|
|
||||||
<td><div class="m"></div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--spacing-l)</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>16</td>
|
|
||||||
<td><div class="l"></div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--spacing-xl)</td>
|
|
||||||
<td>1.25</td>
|
|
||||||
<td>20</td>
|
|
||||||
<td><div class="xl"></div></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h2>Layout</h2>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Var</th>
|
|
||||||
<th>rem</th>
|
|
||||||
<th>px</th>
|
|
||||||
<th>Visual</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--layout-xs)</td>
|
|
||||||
<td>1.25</td>
|
|
||||||
<td>20</td>
|
|
||||||
<td><div class="layout-xs"></div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--layout-s)</td>
|
|
||||||
<td>1.5</td>
|
|
||||||
<td>24</td>
|
|
||||||
<td><div class="layout-s"></div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--layout-m)</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>32</td>
|
|
||||||
<td><div class="layout-m"></div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--layout-l)</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>48</td>
|
|
||||||
<td><div class="layout-l"></div></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>var(--layout-xl)</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>64</td>
|
|
||||||
<td><div class="layout-xl"></div></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
table {
|
|
||||||
font-family: var(--font-sans);
|
|
||||||
border-collapse: collapse;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
display: inline-block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: var(--spacing-s) var(--spacing-l);
|
|
||||||
margin: var(--spacing-s) 0;
|
|
||||||
background-color: var(--grey-2);
|
|
||||||
color: var(--red-dark);
|
|
||||||
border-radius: var(--spacing-xs);
|
|
||||||
}
|
|
||||||
|
|
||||||
td, th {
|
|
||||||
border: 1px solid var(--grey-4);
|
|
||||||
text-align: left;
|
|
||||||
padding: var(--spacing-m);
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:nth-child(even) {
|
|
||||||
background-color: var(--grey-3);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
margin: var(--layout-xl) 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.xs {
|
|
||||||
height: var(--spacing-xs);
|
|
||||||
width: var(--spacing-xs);
|
|
||||||
background-color: var(--purple);
|
|
||||||
}
|
|
||||||
|
|
||||||
.s {
|
|
||||||
height: var(--spacing-s);
|
|
||||||
width: var(--spacing-s);
|
|
||||||
background-color: var(--purple);
|
|
||||||
}
|
|
||||||
|
|
||||||
.m {
|
|
||||||
height: var(--spacing-m);
|
|
||||||
width: var(--spacing-m);
|
|
||||||
background-color: var(--purple);
|
|
||||||
}
|
|
||||||
|
|
||||||
.l {
|
|
||||||
height: var(--spacing-l);
|
|
||||||
width: var(--spacing-l);
|
|
||||||
background-color: var(--purple);
|
|
||||||
}
|
|
||||||
|
|
||||||
.xl {
|
|
||||||
height: var(--spacing-xl);
|
|
||||||
width: var(--spacing-xl);
|
|
||||||
background-color: var(--purple);
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-xs {
|
|
||||||
height: var(--layout-xs);
|
|
||||||
width: var(--layout-xs);
|
|
||||||
background-color: var(--blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-s {
|
|
||||||
height: var(--layout-s);
|
|
||||||
width: var(--layout-s);
|
|
||||||
background-color: var(--blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-m {
|
|
||||||
height: var(--layout-m);
|
|
||||||
width: var(--layout-m);
|
|
||||||
background-color: var(--blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-l {
|
|
||||||
height: var(--layout-l);
|
|
||||||
width: var(--layout-l);
|
|
||||||
background-color: var(--blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout-xl {
|
|
||||||
height: var(--layout-xl);
|
|
||||||
width: var(--layout-xl);
|
|
||||||
background-color: var(--blue);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,227 +0,0 @@
|
||||||
<script>
|
|
||||||
import { View } from "svench";
|
|
||||||
import Heading from "./Heading.svelte";
|
|
||||||
import Body from "./Body.svelte";
|
|
||||||
import Label from "./Label.svelte";
|
|
||||||
|
|
||||||
const username = "bbuserexample";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.typography-container {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.typography-column {
|
|
||||||
padding: var(--spacing-l);
|
|
||||||
}
|
|
||||||
|
|
||||||
.typography-column--grey {
|
|
||||||
background-color: var(--grey-5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.label-wrapper {
|
|
||||||
padding: var(--spacing-m);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<h1 class="bb-heading bb-heading--large bb-heading--heavy">Typography</h1>
|
|
||||||
<p>
|
|
||||||
Budibase uses Inter as its typeface and three types can be used,
|
|
||||||
<strong>heading</strong>
|
|
||||||
,
|
|
||||||
<strong>body</strong>
|
|
||||||
and
|
|
||||||
<strong>label</strong>
|
|
||||||
</p>
|
|
||||||
<p>Each type has 5 sizes, xs, s, m l and xl.</p>
|
|
||||||
<p>Each type is available in the colors white, grey or black.</p>
|
|
||||||
|
|
||||||
<View name="Heading">
|
|
||||||
<div class="typography-container">
|
|
||||||
<div class="typography-column">
|
|
||||||
<Heading extraLarge black>Heading Extra Large Black</Heading>
|
|
||||||
|
|
||||||
<Heading large black>Heading Large Black</Heading>
|
|
||||||
|
|
||||||
<Heading medium black>Heading Medium Black</Heading>
|
|
||||||
|
|
||||||
<Heading small black>Heading Small Black</Heading>
|
|
||||||
|
|
||||||
<Heading extraSmall black>Heading Extra Small Black</Heading>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="typography-column">
|
|
||||||
<Heading extraLarge grey>Heading Extra Large Grey</Heading>
|
|
||||||
|
|
||||||
<Heading large grey>Heading Large Grey</Heading>
|
|
||||||
|
|
||||||
<Heading medium grey>Heading Medium Grey</Heading>
|
|
||||||
|
|
||||||
<Heading small grey>Heading Small Grey</Heading>
|
|
||||||
|
|
||||||
<Heading extraSmall grey>Heading Extra Small Grey</Heading>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="typography-column typography-column--grey">
|
|
||||||
<Heading extraLarge white>Heading Extra Large White</Heading>
|
|
||||||
|
|
||||||
<Heading large white>Heading Large White</Heading>
|
|
||||||
|
|
||||||
<Heading medium white>Heading Medium White</Heading>
|
|
||||||
|
|
||||||
<Heading small white>Heading Small White</Heading>
|
|
||||||
|
|
||||||
<Heading extraSmall white>Heading Extra Small White</Heading>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="typography-column">
|
|
||||||
<Heading extraLarge black lh>Heading Extra Large Black Line Height</Heading>
|
|
||||||
|
|
||||||
<Heading large black lh>Heading Large Black Line Height</Heading>
|
|
||||||
|
|
||||||
<Heading medium black lh>Heading Medium Black Line Height</Heading>
|
|
||||||
|
|
||||||
<Heading small black lh>Heading Small Black Line Height</Heading>
|
|
||||||
|
|
||||||
<Heading extraSmall black lh>Heading Extra Small Black Line Height</Heading>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="Body">
|
|
||||||
<div class="typography-container">
|
|
||||||
<div class="typography-column">
|
|
||||||
<Body extraLarge black>Body Extra Large Black</Body>
|
|
||||||
|
|
||||||
<Body large black>Body Large Black</Body>
|
|
||||||
|
|
||||||
<Body medium black>Body Medium Black</Body>
|
|
||||||
|
|
||||||
<Body small black>Body Small Black</Body>
|
|
||||||
|
|
||||||
<Body extraSmall black>Body Extra Small Black</Body>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="typography-column">
|
|
||||||
<Body extraLarge lh black>Body Extra Large Black Line-height</Body>
|
|
||||||
|
|
||||||
<Body large lh black>Body Large Black Line-height</Body>
|
|
||||||
|
|
||||||
<Body medium lh black>Body Medium Black Line-height</Body>
|
|
||||||
|
|
||||||
<Body small lh black>Body Small Black Line-height</Body>
|
|
||||||
|
|
||||||
<Body extraSmall lh black>Body Extra Small Black Line-height</Body>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="typography-column">
|
|
||||||
<Body extraLarge grey>Body Extra Large Grey</Body>
|
|
||||||
|
|
||||||
<Body large grey>Body Large Grey</Body>
|
|
||||||
|
|
||||||
<Body medium grey>Body Medium Grey</Body>
|
|
||||||
|
|
||||||
<Body small grey>Body Small Grey</Body>
|
|
||||||
|
|
||||||
<Body extraSmall grey>Body Extra Small Grey</Body>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="typography-column typography-column--grey">
|
|
||||||
<Body extraLarge white>Body Extra Large White</Body>
|
|
||||||
|
|
||||||
<Body large white>Body Large White</Body>
|
|
||||||
|
|
||||||
<Body medium white>Body Medium White</Body>
|
|
||||||
|
|
||||||
<Body small white>Body Small White</Body>
|
|
||||||
|
|
||||||
<Body extraSmall white>Body Extra Small White</Body>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="Label">
|
|
||||||
<div class="typography-container">
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label extraLarge black forAttr={username}>Label Extra Large Black</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label large black forAttr={username}>Label Large Black</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label medium black forAttr={username}>Label Medium Black</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label small black forAttr={username}>Label Small Black</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label extraSmall black forAttr={username}>Label Extra Small Black</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="typography-container">
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label extraLarge grey forAttr={username}>Label Extra Large Grey</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label large grey forAttr={username}>Label Large Grey</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label medium grey forAttr={username}>Label Medium Grey</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label small grey forAttr={username}>Label Small Grey</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label extraSmall grey forAttr={username}>Label Extra Small Grey</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="typography-container typography-column--grey">
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label extraLarge white forAttr={username}>Label Extra Large White</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label large white forAttr={username}>Label Large White</Label>
|
|
||||||
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label medium white forAttr={username}>Label Medium White</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label small white forAttr={username}>Label Small White</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label-wrapper">
|
|
||||||
<Label extraSmall white forAttr={username}>Label Extra Small White</Label>
|
|
||||||
<input type="text" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</View>
|
|
|
@ -5,24 +5,28 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label
|
<label
|
||||||
class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized">
|
class="spectrum-Checkbox spectrum-Checkbox--sizeM spectrum-Checkbox--emphasized"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="spectrum-Checkbox-input"
|
class="spectrum-Checkbox-input"
|
||||||
id="checkbox-1"
|
id="checkbox-1"
|
||||||
disabled
|
disabled
|
||||||
checked={!!value} />
|
checked={!!value}
|
||||||
|
/>
|
||||||
<span class="spectrum-Checkbox-box">
|
<span class="spectrum-Checkbox-box">
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
|
class="spectrum-Icon spectrum-UIIcon-Checkmark100 spectrum-Checkbox-checkmark"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
<use xlink:href="#spectrum-css-icon-Checkmark100" />
|
||||||
</svg>
|
</svg>
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark"
|
class="spectrum-Icon spectrum-UIIcon-Dash100 spectrum-Checkbox-partialCheckmark"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Dash100" />
|
<use xlink:href="#spectrum-css-icon-Dash100" />
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
}
|
}
|
||||||
$: type = schema?.type ?? "string"
|
$: type = schema?.type ?? "string"
|
||||||
$: customRenderer = customRenderers?.find(x => x.column === schema?.name)
|
$: customRenderer = customRenderers?.find(x => x.column === schema?.name)
|
||||||
$: renderer = customRenderer?.component ?? typeMap[type]
|
$: renderer = customRenderer?.component ?? typeMap[type] ?? StringRenderer
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if renderer && (customRenderer || (value != null && value !== ''))}
|
{#if renderer && (customRenderer || (value != null && value !== ""))}
|
||||||
<svelte:component this={renderer} {row} {schema} {value} on:clickrelationship>
|
<svelte:component this={renderer} {row} {schema} {value} on:clickrelationship>
|
||||||
<slot />
|
<slot />
|
||||||
</svelte:component>
|
</svelte:component>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
export let value
|
export let value
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>{dayjs(value).format('MMMM D YYYY, HH:mm')}</div>
|
<div>{dayjs(value).format("MMMM D YYYY, HH:mm")}</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
div {
|
div {
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
// Table state
|
// Table state
|
||||||
let height = 0
|
let height = 0
|
||||||
let loaded = false
|
let loaded = false
|
||||||
|
$: schema = fixSchema(schema)
|
||||||
$: if (!loading) loaded = true
|
$: if (!loading) loaded = true
|
||||||
$: rows = data ?? []
|
$: rows = data ?? []
|
||||||
$: visibleRowCount = getVisibleRowCount(loaded, height, rows.length, rowCount)
|
$: visibleRowCount = getVisibleRowCount(loaded, height, rows.length, rowCount)
|
||||||
|
@ -50,7 +51,7 @@
|
||||||
rows.length
|
rows.length
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reset state when data chanegs
|
// Reset state when data changes
|
||||||
$: data.length, reset()
|
$: data.length, reset()
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
nextScrollTop = 0
|
nextScrollTop = 0
|
||||||
|
@ -59,6 +60,24 @@
|
||||||
timeout = null
|
timeout = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fixSchema = schema => {
|
||||||
|
let fixedSchema = {}
|
||||||
|
Object.entries(schema || {}).forEach(([fieldName, fieldSchema]) => {
|
||||||
|
if (typeof fieldSchema === "string") {
|
||||||
|
fixedSchema[fieldName] = {
|
||||||
|
type: fieldSchema,
|
||||||
|
name: fieldName,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fixedSchema[fieldName] = {
|
||||||
|
...fieldSchema,
|
||||||
|
name: fieldName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return fixedSchema
|
||||||
|
}
|
||||||
|
|
||||||
const getVisibleRowCount = (loaded, height, allRows, rowCount) => {
|
const getVisibleRowCount = (loaded, height, allRows, rowCount) => {
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
return rowCount || 0
|
return rowCount || 0
|
||||||
|
@ -118,7 +137,6 @@
|
||||||
if (!field || !fieldSchema) {
|
if (!field || !fieldSchema) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
schema[field].name = field
|
|
||||||
if (!fieldSchema?.autocolumn) {
|
if (!fieldSchema?.autocolumn) {
|
||||||
columns.push(fieldSchema)
|
columns.push(fieldSchema)
|
||||||
} else if (showAutoColumns) {
|
} else if (showAutoColumns) {
|
||||||
|
@ -192,16 +210,17 @@
|
||||||
on:scroll={onScroll}
|
on:scroll={onScroll}
|
||||||
class:quiet
|
class:quiet
|
||||||
style={`--row-height: ${rowHeight}px; --header-height: ${headerHeight}px;`}
|
style={`--row-height: ${rowHeight}px; --header-height: ${headerHeight}px;`}
|
||||||
class="container">
|
class="container"
|
||||||
|
>
|
||||||
<div style={contentStyle}>
|
<div style={contentStyle}>
|
||||||
<table class="spectrum-Table" class:spectrum-Table--quiet={quiet}>
|
<table class="spectrum-Table" class:spectrum-Table--quiet={quiet}>
|
||||||
{#if sortedRows?.length}
|
{#if fields.length}
|
||||||
<thead class="spectrum-Table-head">
|
<thead class="spectrum-Table-head">
|
||||||
<tr>
|
<tr>
|
||||||
{#if showEditColumn}
|
{#if showEditColumn}
|
||||||
<th class="spectrum-Table-headCell">
|
<th class="spectrum-Table-headCell">
|
||||||
<div class="spectrum-Table-headCell-content">
|
<div class="spectrum-Table-headCell-content">
|
||||||
{editColumnTitle || ''}
|
{editColumnTitle || ""}
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -209,15 +228,19 @@
|
||||||
<th
|
<th
|
||||||
class="spectrum-Table-headCell"
|
class="spectrum-Table-headCell"
|
||||||
class:is-sortable={schema[field].sortable !== false}
|
class:is-sortable={schema[field].sortable !== false}
|
||||||
class:is-sorted-desc={sortColumn === field && sortOrder === 'Descending'}
|
class:is-sorted-desc={sortColumn === field &&
|
||||||
class:is-sorted-asc={sortColumn === field && sortOrder === 'Ascending'}
|
sortOrder === "Descending"}
|
||||||
on:click={() => sortBy(schema[field])}>
|
class:is-sorted-asc={sortColumn === field &&
|
||||||
|
sortOrder === "Ascending"}
|
||||||
|
on:click={() => sortBy(schema[field])}
|
||||||
|
>
|
||||||
<div class="spectrum-Table-headCell-content">
|
<div class="spectrum-Table-headCell-content">
|
||||||
<div class="title">{getDisplayName(schema[field])}</div>
|
<div class="title">{getDisplayName(schema[field])}</div>
|
||||||
{#if schema[field]?.autocolumn}
|
{#if schema[field]?.autocolumn}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Table-autoIcon"
|
class="spectrum-Icon spectrum-Table-autoIcon"
|
||||||
focusable="false">
|
focusable="false"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-MagicWand" />
|
<use xlink:href="#spectrum-icon-18-MagicWand" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -225,7 +248,8 @@
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-UIIcon-ArrowDown100 spectrum-Table-sortedIcon"
|
class="spectrum-Icon spectrum-UIIcon-ArrowDown100 spectrum-Table-sortedIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Arrow100" />
|
<use xlink:href="#spectrum-css-icon-Arrow100" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -233,7 +257,8 @@
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Table-editIcon"
|
class="spectrum-Icon spectrum-Table-editIcon"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
on:click={e => editColumn(e, field)}>
|
on:click={e => editColumn(e, field)}
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-Edit" />
|
<use xlink:href="#spectrum-icon-18-Edit" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -244,16 +269,18 @@
|
||||||
</thead>
|
</thead>
|
||||||
{/if}
|
{/if}
|
||||||
<tbody class="spectrum-Table-body">
|
<tbody class="spectrum-Table-body">
|
||||||
{#if sortedRows?.length}
|
{#if sortedRows?.length && fields.length}
|
||||||
{#each sortedRows as row, idx}
|
{#each sortedRows as row, idx}
|
||||||
<tr
|
<tr
|
||||||
on:click={() => toggleSelectRow(row)}
|
on:click={() => toggleSelectRow(row)}
|
||||||
class="spectrum-Table-row"
|
class="spectrum-Table-row"
|
||||||
class:hidden={idx < firstVisibleRow || idx > lastVisibleRow}>
|
class:hidden={idx < firstVisibleRow || idx > lastVisibleRow}
|
||||||
|
>
|
||||||
{#if idx >= firstVisibleRow && idx <= lastVisibleRow}
|
{#if idx >= firstVisibleRow && idx <= lastVisibleRow}
|
||||||
{#if showEditColumn}
|
{#if showEditColumn}
|
||||||
<td
|
<td
|
||||||
class="spectrum-Table-cell spectrum-Table-cell--divider">
|
class="spectrum-Table-cell spectrum-Table-cell--divider"
|
||||||
|
>
|
||||||
<div class="spectrum-Table-cell-content">
|
<div class="spectrum-Table-cell-content">
|
||||||
<SelectEditRenderer
|
<SelectEditRenderer
|
||||||
data={row}
|
data={row}
|
||||||
|
@ -261,21 +288,25 @@
|
||||||
onToggleSelection={() => toggleSelectRow(row)}
|
onToggleSelection={() => toggleSelectRow(row)}
|
||||||
onEdit={e => editRow(e, row)}
|
onEdit={e => editRow(e, row)}
|
||||||
{allowSelectRows}
|
{allowSelectRows}
|
||||||
{allowEditRows} />
|
{allowEditRows}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{/if}
|
{/if}
|
||||||
{#each fields as field}
|
{#each fields as field}
|
||||||
<td
|
<td
|
||||||
class="spectrum-Table-cell"
|
class="spectrum-Table-cell"
|
||||||
class:spectrum-Table-cell--divider={!!schema[field].divider}>
|
class:spectrum-Table-cell--divider={!!schema[field]
|
||||||
|
.divider}
|
||||||
|
>
|
||||||
<div class="spectrum-Table-cell-content">
|
<div class="spectrum-Table-cell-content">
|
||||||
<CellRenderer
|
<CellRenderer
|
||||||
{customRenderers}
|
{customRenderers}
|
||||||
{row}
|
{row}
|
||||||
schema={schema[field]}
|
schema={schema[field]}
|
||||||
value={row[field]}
|
value={row[field]}
|
||||||
on:clickrelationship>
|
on:clickrelationship
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</CellRenderer>
|
</CellRenderer>
|
||||||
</div>
|
</div>
|
||||||
|
@ -285,14 +316,25 @@
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
<div class="placeholder">
|
<tr class="placeholder-row">
|
||||||
<svg
|
{#if showEditColumn}
|
||||||
class="spectrum-Icon spectrum-Icon--sizeXXL"
|
<td class="placeholder-offset" />
|
||||||
focusable="false">
|
{/if}
|
||||||
<use xlink:href="#spectrum-icon-18-Table" />
|
{#each fields as field}
|
||||||
</svg>
|
<td />
|
||||||
<div>No rows found</div>
|
{/each}
|
||||||
</div>
|
<div class="placeholder" class:has-fields={fields.length > 0}>
|
||||||
|
<div class="placeholder-content">
|
||||||
|
<svg
|
||||||
|
class="spectrum-Icon spectrum-Icon--sizeXXL"
|
||||||
|
focusable="false"
|
||||||
|
>
|
||||||
|
<use xlink:href="#spectrum-icon-18-Table" />
|
||||||
|
</svg>
|
||||||
|
<div>No rows found</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</tr>
|
||||||
{/if}
|
{/if}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -315,7 +357,7 @@
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
.container.quiet {
|
.container.quiet {
|
||||||
border: none !important;
|
border: none;
|
||||||
}
|
}
|
||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -349,7 +391,7 @@
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
background-color: var(--spectrum-alias-background-color-secondary);
|
background-color: var(--spectrum-alias-background-color-secondary);
|
||||||
border-bottom: 1px solid
|
border-bottom: 1px solid
|
||||||
var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid)) !important;
|
var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid));
|
||||||
}
|
}
|
||||||
.spectrum-Table-headCell-content {
|
.spectrum-Table-headCell-content {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -364,7 +406,34 @@
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.placeholder-row {
|
||||||
|
position: relative;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
.placeholder-row td {
|
||||||
|
border-top: none !important;
|
||||||
|
border-bottom: none !important;
|
||||||
|
}
|
||||||
|
.placeholder-offset {
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
.placeholder {
|
.placeholder {
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.placeholder.has-fields {
|
||||||
|
top: var(--header-height);
|
||||||
|
height: calc(100% - var(--header-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-content {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -375,12 +444,13 @@
|
||||||
var(--spectrum-alias-text-color)
|
var(--spectrum-alias-text-color)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
.placeholder div {
|
.placeholder-content div {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-size: var(
|
font-size: var(
|
||||||
--spectrum-table-cell-text-size,
|
--spectrum-table-cell-text-size,
|
||||||
var(--spectrum-alias-font-size-default)
|
var(--spectrum-alias-font-size-default)
|
||||||
);
|
);
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbody {
|
tbody {
|
||||||
|
@ -399,17 +469,17 @@
|
||||||
td {
|
td {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
border-bottom: none !important;
|
border-bottom: none;
|
||||||
border-top: 1px solid
|
border-top: 1px solid
|
||||||
var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid)) !important;
|
var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid));
|
||||||
border-radius: 0 !important;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
tr:first-child td {
|
tr:first-child td {
|
||||||
border-top: none !important;
|
border-top: none;
|
||||||
}
|
}
|
||||||
tr:last-child td {
|
tr:last-child td {
|
||||||
border-bottom: 1px solid
|
border-bottom: 1px solid
|
||||||
var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid)) !important;
|
var(--spectrum-table-border-color, var(--spectrum-alias-border-color-mid));
|
||||||
}
|
}
|
||||||
td.spectrum-Table-cell--divider {
|
td.spectrum-Table-cell--divider {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
|
|
|
@ -30,13 +30,15 @@
|
||||||
on:click={onClick}
|
on:click={onClick}
|
||||||
class:is-selected={$selected.title === title}
|
class:is-selected={$selected.title === title}
|
||||||
class="spectrum-Tabs-item"
|
class="spectrum-Tabs-item"
|
||||||
tabindex="0">
|
tabindex="0"
|
||||||
|
>
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<svg
|
<svg
|
||||||
class="spectrum-Icon spectrum-Icon--sizeM"
|
class="spectrum-Icon spectrum-Icon--sizeM"
|
||||||
focusable="false"
|
focusable="false"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
aria-label="Folder">
|
aria-label="Folder"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-18-{icon}" />
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -44,23 +44,22 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
function id() {
|
function id() {
|
||||||
return (
|
return "_" + Math.random().toString(36).substr(2, 9)
|
||||||
"_" +
|
|
||||||
Math.random()
|
|
||||||
.toString(36)
|
|
||||||
.substr(2, 9)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
bind:this={container}
|
bind:this={container}
|
||||||
class="selected-border spectrum-Tabs spectrum-Tabs--{vertical ? 'vertical' : 'horizontal'}">
|
class="selected-border spectrum-Tabs spectrum-Tabs--{vertical
|
||||||
|
? 'vertical'
|
||||||
|
: 'horizontal'}"
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
{#if $tab.info}
|
{#if $tab.info}
|
||||||
<div
|
<div
|
||||||
class="spectrum-Tabs-selectionIndicator indicator-transition"
|
class="spectrum-Tabs-selectionIndicator indicator-transition"
|
||||||
style="width: {width}; height: {height}; left: {left}; top: {top};" />
|
style="width: {width}; height: {height}; left: {left}; top: {top};"
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,34 @@
|
||||||
<script>
|
<script>
|
||||||
import Avatar from '../Avatar/Avatar.svelte'
|
import Avatar from "../Avatar/Avatar.svelte"
|
||||||
import ClearButton from '../ClearButton/ClearButton.svelte'
|
import ClearButton from "../ClearButton/ClearButton.svelte"
|
||||||
export let icon = "";
|
export let icon = ""
|
||||||
export let avatar = "";
|
export let avatar = ""
|
||||||
export let invalid = false;
|
export let invalid = false
|
||||||
export let disabled = false;
|
export let disabled = false
|
||||||
export let closable = false;
|
export let closable = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class:is-invalid={invalid} class:is-disabled={disabled} class="spectrum-Tags-item" role="listitem">
|
<div
|
||||||
|
class:is-invalid={invalid}
|
||||||
|
class:is-disabled={disabled}
|
||||||
|
class="spectrum-Tags-item"
|
||||||
|
role="listitem"
|
||||||
|
>
|
||||||
{#if avatar}
|
{#if avatar}
|
||||||
<Avatar url={avatar} />
|
<Avatar url={avatar} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if icon}
|
{#if icon}
|
||||||
<svg class="spectrum-Icon spectrum-Icon--sizeS" focusable="false" aria-hidden="true" aria-label="Tag">
|
<svg
|
||||||
|
class="spectrum-Icon spectrum-Icon--sizeS"
|
||||||
|
focusable="false"
|
||||||
|
aria-hidden="true"
|
||||||
|
aria-label="Tag"
|
||||||
|
>
|
||||||
<use xlink:href="#spectrum-icon-24-{icon}" />
|
<use xlink:href="#spectrum-icon-24-{icon}" />
|
||||||
</svg>
|
</svg>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="spectrum-Tags-itemLabel"><slot /></span>
|
<span class="spectrum-Tags-itemLabel"><slot /></span>
|
||||||
{#if closable}
|
{#if closable}
|
||||||
<ClearButton on:click />
|
<ClearButton on:click />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/tags/dist/index-vars.css"
|
import "@spectrum-css/tags/dist/index-vars.css"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="spectrum-Tags" role="list" aria-label="list">
|
<div class="spectrum-Tags" role="list" aria-label="list">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,28 +1,40 @@
|
||||||
<script>
|
<script>
|
||||||
export let selected = false;
|
export let selected = false
|
||||||
export let open = false;
|
export let open = false
|
||||||
export let title;
|
export let title
|
||||||
export let icon;
|
export let icon
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
class:is-selected={selected} class:is-open={open} class="spectrum-TreeView-item">
|
class:is-selected={selected}
|
||||||
<a on:click class="spectrum-TreeView-itemLink" href="#">
|
class:is-open={open}
|
||||||
{#if $$slots.default}
|
class="spectrum-TreeView-item"
|
||||||
<svg class="spectrum-Icon spectrum-UIIcon-ChevronRight100 spectrum-TreeView-itemIndicator" focusable="false" aria-hidden="true">
|
>
|
||||||
<use xlink:href="#spectrum-css-icon-Chevron100" />
|
<a on:click class="spectrum-TreeView-itemLink" href="#">
|
||||||
</svg>
|
{#if $$slots.default}
|
||||||
{/if}
|
<svg
|
||||||
{#if icon}
|
class="spectrum-Icon spectrum-UIIcon-ChevronRight100 spectrum-TreeView-itemIndicator"
|
||||||
<svg class="spectrum-TreeView-itemIcon spectrum-Icon spectrum-Icon--sizeM" focusable="false" aria-hidden="true" aria-label="Layers">
|
focusable="false"
|
||||||
<use xlink:href="#spectrum-icon-18-{icon}" />
|
aria-hidden="true"
|
||||||
</svg>
|
>
|
||||||
{/if}
|
<use xlink:href="#spectrum-css-icon-Chevron100" />
|
||||||
<span class="spectrum-TreeView-itemLabel">{title}</span>
|
</svg>
|
||||||
</a>
|
{/if}
|
||||||
{#if $$slots.default}
|
{#if icon}
|
||||||
<ul class="spectrum-TreeView">
|
<svg
|
||||||
<slot />
|
class="spectrum-TreeView-itemIcon spectrum-Icon spectrum-Icon--sizeM"
|
||||||
</ul>
|
focusable="false"
|
||||||
{/if}
|
aria-hidden="true"
|
||||||
</li>
|
aria-label="Layers"
|
||||||
|
>
|
||||||
|
<use xlink:href="#spectrum-icon-18-{icon}" />
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
|
<span class="spectrum-TreeView-itemLabel">{title}</span>
|
||||||
|
</a>
|
||||||
|
{#if $$slots.default}
|
||||||
|
<ul class="spectrum-TreeView">
|
||||||
|
<slot />
|
||||||
|
</ul>
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/treeview/dist/index-vars.css"
|
import "@spectrum-css/treeview/dist/index-vars.css"
|
||||||
|
|
||||||
export let quiet = false
|
export let quiet = false
|
||||||
export let standalone = true
|
export let standalone = true
|
||||||
export let width = '250px';
|
export let width = "250px"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ul class:spectrum-TreeView--standalone={standalone} class:spectrum-TreeView--quiet={quiet} class="spectrum-TreeView" style="width: {width}">
|
<ul
|
||||||
<slot />
|
class:spectrum-TreeView--standalone={standalone}
|
||||||
</ul>
|
class:spectrum-TreeView--quiet={quiet}
|
||||||
|
class="spectrum-TreeView"
|
||||||
|
style="width: {width}"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</ul>
|
||||||
|
|
|
@ -1,29 +1,22 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/typography/dist/index-vars.css"
|
import "@spectrum-css/typography/dist/index-vars.css"
|
||||||
|
|
||||||
// Sizes
|
export let size = "M"
|
||||||
export let xxxl = false;
|
export let serif = false
|
||||||
export let xxl = false;
|
export let noPadding = false
|
||||||
export let xl = false;
|
|
||||||
export let l = false;
|
|
||||||
export let m = false;
|
|
||||||
export let s = false;
|
|
||||||
export let xs = false;
|
|
||||||
export let xxs = false;
|
|
||||||
|
|
||||||
export let serif = false;
|
|
||||||
$: useDefault = ![xxxl, xxl, xl, l, m, s, xs, xxs].includes(true)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<p class="spectrum-Body"
|
<p
|
||||||
class:spectrum-Body--serif={serif}
|
class:noPadding
|
||||||
class:spectrum-Body--sizeXXXL={xxxl}
|
class="spectrum-Body spectrum-Body--size{size}"
|
||||||
class:spectrum-Body--sizeXXL={xxl}
|
class:spectrum-Body--serif={serif}
|
||||||
class:spectrum-Body--sizeXL={xl}
|
>
|
||||||
class:spectrum-Body--sizeL={l}
|
<slot />
|
||||||
class:spectrum-Body--sizeM={m || useDefault}
|
</p>
|
||||||
class:spectrum-Body--sizeS={s}
|
|
||||||
class:spectrum-Body--sizeXS={xs}
|
<style>
|
||||||
class:spectrum-Body--sizeXXS={xxs}>
|
.noPadding {
|
||||||
<slot />
|
padding: 0;
|
||||||
</p>
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,20 +1,10 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/typography/dist/index-vars.css"
|
import "@spectrum-css/typography/dist/index-vars.css"
|
||||||
|
|
||||||
// Sizes
|
// Sizes
|
||||||
export let xl = false;
|
export let size = "M"
|
||||||
export let l = false;
|
|
||||||
export let m = false;
|
|
||||||
export let s = false;
|
|
||||||
export let xs = false;
|
|
||||||
$: useDefault = ![xl, l, m, s, xs].includes(true)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<code class="spectrum-Code"
|
<code class="spectrum-Code spectrum-Code--size{size}">
|
||||||
class:spectrum-Code--sizeXL={xl}
|
<slot />
|
||||||
class:spectrum-Code--sizeL={l}
|
</code>
|
||||||
class:spectrum-Code--sizeM={m || useDefault}
|
|
||||||
class:spectrum-Code--sizeS={s}
|
|
||||||
class:spectrum-Code--sizeXS={xs}>
|
|
||||||
<slot />
|
|
||||||
</code>
|
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
import "@spectrum-css/typography/dist/index-vars.css"
|
import "@spectrum-css/typography/dist/index-vars.css"
|
||||||
|
|
||||||
// Sizes
|
// Sizes
|
||||||
export let xl = false;
|
export let size = "M"
|
||||||
export let l = false;
|
|
||||||
export let m = false;
|
|
||||||
export let s = false;
|
|
||||||
|
|
||||||
export let serif = false;
|
export let serif = false
|
||||||
$: useDefault = ![xl, l, m, s].includes(true)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<p class="spectrum-Detail"
|
<p
|
||||||
class:spectrum-Detail--serif={serif}
|
class="spectrum-Detail spectrum-Detail--size{size}"
|
||||||
class:spectrum-Detail--sizeXL={xl}
|
class:spectrum-Detail--serif={serif}
|
||||||
class:spectrum-Detail--sizeL={l}
|
>
|
||||||
class:spectrum-Detail--sizeM={m || useDefault}
|
<slot />
|
||||||
class:spectrum-Detail--sizeS={s}>
|
</p>
|
||||||
<slot />
|
|
||||||
</p>
|
|
||||||
|
|
|
@ -2,27 +2,9 @@
|
||||||
import "@spectrum-css/typography/dist/index-vars.css"
|
import "@spectrum-css/typography/dist/index-vars.css"
|
||||||
|
|
||||||
// Sizes
|
// Sizes
|
||||||
export let xxxl = false
|
export let size = "M"
|
||||||
export let xxl = false
|
|
||||||
export let xl = false
|
|
||||||
export let l = false
|
|
||||||
export let m = false
|
|
||||||
export let s = false
|
|
||||||
export let xs = false
|
|
||||||
export let xxs = false
|
|
||||||
|
|
||||||
$: useDefault = ![xxxl, xxl, xl, l, m, s, xs, xxs].includes(true)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1
|
<h1 class="spectrum-Heading spectrum-Heading--size{size}">
|
||||||
class="spectrum-Heading"
|
|
||||||
class:spectrum-Heading--sizeXXXL={xxxl}
|
|
||||||
class:spectrum-Heading--sizeXXL={xxl}
|
|
||||||
class:spectrum-Heading--sizeXL={xl}
|
|
||||||
class:spectrum-Heading--sizeL={l}
|
|
||||||
class:spectrum-Heading--sizeM={m || useDefault}
|
|
||||||
class:spectrum-Heading--sizeS={s}
|
|
||||||
class:spectrum-Heading--sizeXS={xs}
|
|
||||||
class:spectrum-Heading--sizeXXS={xxs}>
|
|
||||||
<slot />
|
<slot />
|
||||||
</h1>
|
</h1>
|
||||||
|
|
|
@ -26,8 +26,9 @@ export { default as DetailSummary } from "./DetailSummary/DetailSummary.svelte"
|
||||||
export { default as Popover } from "./Popover/Popover.svelte"
|
export { default as Popover } from "./Popover/Popover.svelte"
|
||||||
export { default as ProgressBar } from "./ProgressBar/ProgressBar.svelte"
|
export { default as ProgressBar } from "./ProgressBar/ProgressBar.svelte"
|
||||||
export { default as ProgressCircle } from "./ProgressCircle/ProgressCircle.svelte"
|
export { default as ProgressCircle } from "./ProgressCircle/ProgressCircle.svelte"
|
||||||
export { default as Label } from "./Styleguide/Label.svelte"
|
export { default as Label } from "./Label/Label.svelte"
|
||||||
export { default as Layout } from "./Layout/Layout.svelte"
|
export { default as Layout } from "./Layout/Layout.svelte"
|
||||||
|
export { default as Page } from "./Layout/Page.svelte"
|
||||||
export { default as Link } from "./Link/Link.svelte"
|
export { default as Link } from "./Link/Link.svelte"
|
||||||
export { default as Menu } from "./Menu/Menu.svelte"
|
export { default as Menu } from "./Menu/Menu.svelte"
|
||||||
export { default as MenuSection } from "./Menu/Section.svelte"
|
export { default as MenuSection } from "./Menu/Section.svelte"
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue