release: WRNexusJS 0.6.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/ai",
|
"name": "@wrnexus/ai",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.",
|
"description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/authz",
|
"name": "@wrnexus/authz",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/authz — part of the WrNexus framework.",
|
"description": "@wrnexus/authz — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
+13
-13
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/cli",
|
"name": "@wrnexus/cli",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/cli — part of the WrNexus framework.",
|
"description": "@wrnexus/cli — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -28,18 +28,18 @@
|
|||||||
"wrnexus": "./dist/index.js"
|
"wrnexus": "./dist/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/core": "^0.5.14",
|
"@wrnexus/core": "^0.6.0",
|
||||||
"@wrnexus/router": "^0.5.14",
|
"@wrnexus/router": "^0.6.0",
|
||||||
"@wrnexus/csr": "^0.5.14",
|
"@wrnexus/csr": "^0.6.0",
|
||||||
"@wrnexus/compiler": "^0.5.14",
|
"@wrnexus/compiler": "^0.6.0",
|
||||||
"@wrnexus/styles": "^0.5.14",
|
"@wrnexus/styles": "^0.6.0",
|
||||||
"@wrnexus/dev-server": "^0.5.14",
|
"@wrnexus/dev-server": "^0.6.0",
|
||||||
"@wrnexus/ui": "^0.5.14",
|
"@wrnexus/ui": "^0.6.0",
|
||||||
"@wrnexus/validation": "^0.5.14",
|
"@wrnexus/validation": "^0.6.0",
|
||||||
"@wrnexus/i18n": "^0.5.14",
|
"@wrnexus/i18n": "^0.6.0",
|
||||||
"@wrnexus/db": "^0.5.14",
|
"@wrnexus/db": "^0.6.0",
|
||||||
"@wrnexus/plugin": "^0.5.14",
|
"@wrnexus/plugin": "^0.6.0",
|
||||||
"@wrnexus/syntax": "^0.5.14"
|
"@wrnexus/syntax": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/compiler",
|
"name": "@wrnexus/compiler",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/compiler — part of the WrNexus framework.",
|
"description": "@wrnexus/compiler — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/syntax": "^0.5.14"
|
"@wrnexus/syntax": "^0.6.0",
|
||||||
|
"@wrnexus/store": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/core",
|
"name": "@wrnexus/core",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/core — part of the WrNexus framework.",
|
"description": "@wrnexus/core — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/csr",
|
"name": "@wrnexus/csr",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/csr — part of the WrNexus framework.",
|
"description": "@wrnexus/csr — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/core": "^0.5.14"
|
"@wrnexus/core": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/db",
|
"name": "@wrnexus/db",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/db — part of the WrNexus framework.",
|
"description": "@wrnexus/db — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/dev-server",
|
"name": "@wrnexus/dev-server",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/dev-server — part of the WrNexus framework.",
|
"description": "@wrnexus/dev-server — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -25,20 +25,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/core": "^0.5.14",
|
"@wrnexus/core": "^0.6.0",
|
||||||
"@wrnexus/dev-toolbar": "^0.5.14",
|
"@wrnexus/dev-toolbar": "^0.6.0",
|
||||||
"@wrnexus/router": "^0.5.14",
|
"@wrnexus/router": "^0.6.0",
|
||||||
"@wrnexus/ssr": "^0.5.14",
|
"@wrnexus/ssr": "^0.6.0",
|
||||||
"@wrnexus/csr": "^0.5.14",
|
"@wrnexus/csr": "^0.6.0",
|
||||||
"@wrnexus/compiler": "^0.5.14",
|
"@wrnexus/compiler": "^0.6.0",
|
||||||
"@wrnexus/styles": "^0.5.14",
|
"@wrnexus/styles": "^0.6.0",
|
||||||
"@wrnexus/ui": "^0.5.14",
|
"@wrnexus/ui": "^0.6.0",
|
||||||
"@wrnexus/validation": "^0.5.14",
|
"@wrnexus/validation": "^0.6.0",
|
||||||
"@wrnexus/i18n": "^0.5.14",
|
"@wrnexus/i18n": "^0.6.0",
|
||||||
"@wrnexus/db": "^0.5.14",
|
"@wrnexus/db": "^0.6.0",
|
||||||
"@wrnexus/pubsub": "^0.5.14",
|
"@wrnexus/pubsub": "^0.6.0",
|
||||||
"@wrnexus/uploader": "^0.5.14",
|
"@wrnexus/uploader": "^0.6.0",
|
||||||
"@wrnexus/plugin": "^0.5.14"
|
"@wrnexus/plugin": "^0.6.0",
|
||||||
|
"@wrnexus/store": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/dev-toolbar",
|
"name": "@wrnexus/dev-toolbar",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/dev-toolbar — part of the WrNexus framework.",
|
"description": "@wrnexus/dev-toolbar — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/encryption",
|
"name": "@wrnexus/encryption",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/encryption — part of the WrNexus framework.",
|
"description": "@wrnexus/encryption — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/helpers",
|
"name": "@wrnexus/helpers",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "Safe convenience helpers for WrNexus request contexts and common application flows.",
|
"description": "Safe convenience helpers for WrNexus request contexts and common application flows.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/core": "^0.5.14"
|
"@wrnexus/core": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/i18n",
|
"name": "@wrnexus/i18n",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/i18n — part of the WrNexus framework.",
|
"description": "@wrnexus/i18n — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/core": "^0.5.14"
|
"@wrnexus/core": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/jwt",
|
"name": "@wrnexus/jwt",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/jwt — part of the WrNexus framework.",
|
"description": "@wrnexus/jwt — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/mobile",
|
"name": "@wrnexus/mobile",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/mobile — part of the WrNexus framework.",
|
"description": "@wrnexus/mobile — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/native": "^0.5.14"
|
"@wrnexus/native": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/native",
|
"name": "@wrnexus/native",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/native — part of the WrNexus framework.",
|
"description": "@wrnexus/native — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/oauth",
|
"name": "@wrnexus/oauth",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/oauth — part of the WrNexus framework.",
|
"description": "@wrnexus/oauth — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/plugin",
|
"name": "@wrnexus/plugin",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/plugin — part of the WrNexus framework.",
|
"description": "@wrnexus/plugin — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/syntax": "^0.5.14"
|
"@wrnexus/syntax": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/pubsub",
|
"name": "@wrnexus/pubsub",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/pubsub — part of the WrNexus framework.",
|
"description": "@wrnexus/pubsub — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/queue",
|
"name": "@wrnexus/queue",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/queue — part of the WrNexus framework.",
|
"description": "@wrnexus/queue — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/reactive",
|
"name": "@wrnexus/reactive",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/reactive — part of the WrNexus framework.",
|
"description": "@wrnexus/reactive — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/router",
|
"name": "@wrnexus/router",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/router — part of the WrNexus framework.",
|
"description": "@wrnexus/router — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/compiler": "^0.5.14",
|
"@wrnexus/compiler": "^0.6.0",
|
||||||
"@wrnexus/core": "^0.5.14"
|
"@wrnexus/core": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/ssr",
|
"name": "@wrnexus/ssr",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/ssr — part of the WrNexus framework.",
|
"description": "@wrnexus/ssr — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -18,10 +18,19 @@
|
|||||||
".": {
|
".": {
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"import": "./dist/index.js"
|
"import": "./dist/index.js"
|
||||||
|
},
|
||||||
|
"./rpc": {
|
||||||
|
"types": "./dist/rpc.d.ts",
|
||||||
|
"import": "./dist/rpc.js"
|
||||||
|
},
|
||||||
|
"./store-context": {
|
||||||
|
"types": "./dist/store-context.d.ts",
|
||||||
|
"import": "./dist/store-context.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/core": "^0.5.14"
|
"@wrnexus/core": "^0.6.0",
|
||||||
|
"@wrnexus/store": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/styles",
|
"name": "@wrnexus/styles",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/styles — part of the WrNexus framework.",
|
"description": "@wrnexus/styles — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -21,9 +21,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/uploader": "^0.5.14",
|
"@wrnexus/uploader": "^0.6.0",
|
||||||
"@wrnexus/core": "^0.5.14",
|
"@wrnexus/core": "^0.6.0",
|
||||||
"@wrnexus/plugin": "^0.5.14"
|
"@wrnexus/plugin": "^0.6.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/syntax",
|
"name": "@wrnexus/syntax",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/syntax — part of the WrNexus framework.",
|
"description": "@wrnexus/syntax — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/test",
|
"name": "@wrnexus/test",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/test — part of the WrNexus framework.",
|
"description": "@wrnexus/test — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/tracking",
|
"name": "@wrnexus/tracking",
|
||||||
"version": "0.5.14",
|
"version": "0.6.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "@wrnexus/tracking — part of the WrNexus framework.",
|
"description": "@wrnexus/tracking — part of the WrNexus framework.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
+348
-344
File diff suppressed because it is too large
Load Diff
@@ -19,8 +19,7 @@
|
|||||||
{
|
{
|
||||||
"name": "AdvancedSelect",
|
"name": "AdvancedSelect",
|
||||||
"category": "advanced-forms",
|
"category": "advanced-forms",
|
||||||
"purpose": "Theme-aware, responsive advanced select component.",
|
"purpose": "Theme-aware, responsive advanced select component."
|
||||||
"events": ["search", "select", "change", "clear", "open", "close", "load", "error"]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Alert",
|
"name": "Alert",
|
||||||
@@ -29,18 +28,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "AnnouncementBar",
|
"name": "AnnouncementBar",
|
||||||
"category": "blocks",
|
"category": "marketing",
|
||||||
"purpose": "Accessible public announcement, emergency, maintenance, or status bar."
|
"purpose": "Publish a responsive notice with badge, icon, supporting copy, action, dismiss behavior, and width controls."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "AuthForm",
|
"name": "AuthForm",
|
||||||
"category": "forms",
|
"category": "core",
|
||||||
"purpose": "Reusable authentication form for sign-in, registration, recovery, reset, and MFA."
|
"purpose": "Reusable auth form component."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "AuthSplitLayout",
|
"name": "AuthSplitLayout",
|
||||||
"category": "layout",
|
"category": "core",
|
||||||
"purpose": "Responsive 50/50 authentication layout with content and form regions."
|
"purpose": "Reusable auth split layout component."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Avatar",
|
"name": "Avatar",
|
||||||
@@ -55,7 +54,7 @@
|
|||||||
{
|
{
|
||||||
"name": "BackToTop",
|
"name": "BackToTop",
|
||||||
"category": "navigation",
|
"category": "navigation",
|
||||||
"purpose": "Accessible scroll-to-top control with visibility threshold."
|
"purpose": "Provide a responsive floating control that returns long pages to the top and can show scroll progress."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Badge",
|
"name": "Badge",
|
||||||
@@ -70,7 +69,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Breadcrumb",
|
"name": "Breadcrumb",
|
||||||
"category": "navigation",
|
"category": "navigation",
|
||||||
"purpose": "Theme-aware, responsive breadcrumb component."
|
"purpose": "Show responsive hierarchical navigation with home support, separators, current-page state, sizes, and selection events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Button",
|
"name": "Button",
|
||||||
@@ -85,7 +84,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Card",
|
"name": "Card",
|
||||||
"category": "base",
|
"category": "base",
|
||||||
"purpose": "Theme-aware, responsive card component."
|
"purpose": "Group related content in a responsive themed surface with title, description, content, and supporting slots."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Carousel",
|
"name": "Carousel",
|
||||||
@@ -125,13 +124,12 @@
|
|||||||
{
|
{
|
||||||
"name": "Columns",
|
"name": "Columns",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Theme-aware, responsive columns component."
|
"purpose": "Create responsive balanced content columns with configurable count, gap, density, and maximum width."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ComboBox",
|
"name": "ComboBox",
|
||||||
"category": "advanced-forms",
|
"category": "advanced-forms",
|
||||||
"purpose": "Editable autocomplete combobox with local and remote suggestions.",
|
"purpose": "Editable autocomplete combobox with local and remote suggestions."
|
||||||
"events": ["search", "select", "change", "clear", "open", "close", "load", "error"]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Confetti",
|
"name": "Confetti",
|
||||||
@@ -141,12 +139,12 @@
|
|||||||
{
|
{
|
||||||
"name": "Container",
|
"name": "Container",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Theme-aware, responsive container component."
|
"purpose": "Constrain and align page content with responsive gutters and compact, wide, or full width options."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ContextMenu",
|
"name": "ContextMenu",
|
||||||
"category": "overlays",
|
"category": "overlays",
|
||||||
"purpose": "Theme-aware, responsive context menu component."
|
"purpose": "Open an accessible keyboard-aware action menu from pointer or keyboard context interactions."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CopyMarkup",
|
"name": "CopyMarkup",
|
||||||
@@ -155,8 +153,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CTASection",
|
"name": "CTASection",
|
||||||
"category": "blocks",
|
"category": "marketing",
|
||||||
"purpose": "Reusable closing call-to-action section with primary and secondary actions."
|
"purpose": "Close a page or major section with conversion-focused copy, actions, and optional supporting visual content."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "CustomScrollbar",
|
"name": "CustomScrollbar",
|
||||||
@@ -186,7 +184,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Divider",
|
"name": "Divider",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Theme-aware, responsive divider component."
|
"purpose": "Separate related horizontal or vertical content with optional labels, sizes, and semantic colors."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DragAndDrop",
|
"name": "DragAndDrop",
|
||||||
@@ -196,27 +194,27 @@
|
|||||||
{
|
{
|
||||||
"name": "Drawer",
|
"name": "Drawer",
|
||||||
"category": "overlays",
|
"category": "overlays",
|
||||||
"purpose": "Theme-aware, responsive drawer component."
|
"purpose": "Present responsive modal side or bottom content with focus management, backdrop behavior, slots, and close events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Dropdown",
|
"name": "Dropdown",
|
||||||
"category": "overlays",
|
"category": "overlays",
|
||||||
"purpose": "Theme-aware, responsive dropdown component."
|
"purpose": "Open an accessible anchored menu with keyboard navigation, item selection, actions, and responsive placement."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "FeatureCard",
|
"name": "FeatureCard",
|
||||||
"category": "blocks",
|
"category": "marketing",
|
||||||
"purpose": "Reusable linked feature or service card with icon, badge, description, and action."
|
"purpose": "Present one linked feature or service with media, icon, badge, description, and action."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "FeatureGrid",
|
"name": "FeatureGrid",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Responsive equal-height grid for feature and service cards."
|
"purpose": "Arrange feature cards, services, solutions, or benefits in a responsive equal-height grid."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "FeatureIconCard",
|
"name": "FeatureIconCard",
|
||||||
"category": "blocks",
|
"category": "marketing",
|
||||||
"purpose": "Feature card with a prominent themed icon treatment."
|
"purpose": "Present a compact feature or benefit with a styled icon, title, description, badge, and optional link."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "FileInput",
|
"name": "FileInput",
|
||||||
@@ -235,28 +233,28 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Footer",
|
"name": "Footer",
|
||||||
"category": "navigation",
|
"category": "layout",
|
||||||
"purpose": "Responsive application footer with structured links and pre/post content slots."
|
"purpose": "Render structured responsive footer navigation, pre and post content, copyright content, links, and public events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Grid",
|
"name": "Grid",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Theme-aware, responsive grid component."
|
"purpose": "Arrange arbitrary content in a responsive configurable CSS grid with stable columns, gaps, alignment, and width."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Hero",
|
"name": "Hero",
|
||||||
"category": "blocks",
|
"category": "marketing",
|
||||||
"purpose": "Reusable public-page hero with actions, trust items, badges, and visual slots."
|
"purpose": "Build a full-width responsive hero with constrained content, actions, trust signals, and a structured or custom visual panel."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "HeroActions",
|
"name": "HeroActions",
|
||||||
"category": "base",
|
"category": "marketing",
|
||||||
"purpose": "Responsive action group for hero and call-to-action sections."
|
"purpose": "Group hero and campaign actions with consistent alignment, orientation, sizing, and responsive mobile stacking."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Image",
|
"name": "Image",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Theme-aware, responsive image component."
|
"purpose": "Render a responsive image with explicit dimensions, loading behavior, alternative text, sizing, and rounded treatment."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Input",
|
"name": "Input",
|
||||||
@@ -291,12 +289,12 @@
|
|||||||
{
|
{
|
||||||
"name": "Link",
|
"name": "Link",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Theme-aware, responsive link component."
|
"purpose": "Render an accessible internal or external link with target, relation, size, color, and public focus or click events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "List",
|
"name": "List",
|
||||||
"category": "base",
|
"category": "base",
|
||||||
"purpose": "Theme-aware, responsive list component."
|
"purpose": "Present structured responsive linked or status items with icons, descriptions, actions, and selection events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ListGroup",
|
"name": "ListGroup",
|
||||||
@@ -306,17 +304,17 @@
|
|||||||
{
|
{
|
||||||
"name": "Map",
|
"name": "Map",
|
||||||
"category": "integrations",
|
"category": "integrations",
|
||||||
"purpose": "Theme-aware, responsive map component."
|
"purpose": "Present responsive location information and markers with map-ready metadata and movement or marker events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MarketingSectionHeader",
|
"name": "MarketingSectionHeader",
|
||||||
"category": "blocks",
|
"category": "marketing",
|
||||||
"purpose": "Marketing section heading with an optional linked action."
|
"purpose": "Introduce marketing content with an eyebrow, title, description, and optional linked action."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Marquee",
|
"name": "Marquee",
|
||||||
"category": "base",
|
"category": "base",
|
||||||
"purpose": "Theme-aware, responsive marquee component."
|
"purpose": "Continuously present responsive labels, partners, notices, or capabilities with pause and resume behavior."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MegaMenu",
|
"name": "MegaMenu",
|
||||||
@@ -325,18 +323,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MetricCard",
|
"name": "MetricCard",
|
||||||
"category": "blocks",
|
"category": "data",
|
||||||
"purpose": "Single statistic or operational metric with icon, trend, and optional action."
|
"purpose": "Display one operational metric with value, suffix, description, icon, trend, progress, and optional action."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MetricGrid",
|
"name": "MetricGrid",
|
||||||
"category": "layout",
|
"category": "data",
|
||||||
"purpose": "Responsive collection of metric cards."
|
"purpose": "Arrange operational metrics, KPIs, public statistics, or service indicators in a responsive equal-height grid."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Modal",
|
"name": "Modal",
|
||||||
"category": "overlays",
|
"category": "overlays",
|
||||||
"purpose": "Theme-aware, responsive modal component."
|
"purpose": "Present an accessible modal dialog with focus management, confirmation, cancellation, slots, and responsive sizing."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Nav",
|
"name": "Nav",
|
||||||
@@ -350,8 +348,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PageHeader",
|
"name": "PageHeader",
|
||||||
"category": "blocks",
|
"category": "marketing",
|
||||||
"purpose": "Public and application page header with breadcrumbs, metadata, and actions."
|
"purpose": "Introduce an internal or public page with breadcrumbs, icon, title, description, and primary or secondary actions."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Pagination",
|
"name": "Pagination",
|
||||||
@@ -361,23 +359,22 @@
|
|||||||
{
|
{
|
||||||
"name": "PinInput",
|
"name": "PinInput",
|
||||||
"category": "advanced-forms",
|
"category": "advanced-forms",
|
||||||
"purpose": "Secure multi-cell PIN and verification-code input with regex and paste support.",
|
"purpose": "Secure multi-cell PIN and verification-code input with regex and paste support."
|
||||||
"events": ["input", "change", "complete", "paste", "clear", "error"]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Popover",
|
"name": "Popover",
|
||||||
"category": "overlays",
|
"category": "overlays",
|
||||||
"purpose": "Theme-aware, responsive popover component."
|
"purpose": "Display anchored supporting content with configurable trigger, placement, responsive sizing, and open or close events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PortalDashboard",
|
"name": "PortalDashboard",
|
||||||
"category": "blocks",
|
"category": "core",
|
||||||
"purpose": "Responsive portal dashboard with metrics, actions, tasks, and updates."
|
"purpose": "Reusable portal dashboard component."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "PreferenceSwitcher",
|
"name": "PreferenceSwitcher",
|
||||||
"category": "navigation",
|
"category": "core",
|
||||||
"purpose": "Accessible theme, accent color, and language preference controls."
|
"purpose": "Reusable preference switcher component."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Progress",
|
"name": "Progress",
|
||||||
@@ -387,7 +384,7 @@
|
|||||||
{
|
{
|
||||||
"name": "PublicPageShell",
|
"name": "PublicPageShell",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Consistent structural wrapper for public-facing pages."
|
"purpose": "Provide the outer responsive structure, width, background, slots, overflow, and minimum-height behavior for public pages."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Radio",
|
"name": "Radio",
|
||||||
@@ -411,18 +408,18 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SearchBox",
|
"name": "SearchBox",
|
||||||
"category": "advanced-forms",
|
"category": "forms",
|
||||||
"purpose": "Theme-aware, responsive search box component."
|
"purpose": "Provide an accessible responsive search field with labels, validation states, sizes, and input or change events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Section",
|
"name": "Section",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Theme-aware page section with consistent spacing, width, background, and border controls."
|
"purpose": "Create a responsive themed page section with controlled spacing, width, borders, and surface treatment."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SectionHeader",
|
"name": "SectionHeader",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Reusable accessible section heading with eyebrow, title, description, icon, and actions."
|
"purpose": "Introduce a section with an eyebrow, title, description, alignment, and responsive heading hierarchy."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Select",
|
"name": "Select",
|
||||||
@@ -446,13 +443,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "SplitHero",
|
"name": "SplitHero",
|
||||||
"category": "blocks",
|
"category": "marketing",
|
||||||
"purpose": "Two-column hero with configurable content and visual placement."
|
"purpose": "Build a responsive two-column introduction balancing descriptive content with a visual, image, or structured data panel."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "StatsBar",
|
"name": "StatsBar",
|
||||||
"category": "blocks",
|
"category": "data",
|
||||||
"purpose": "Compact responsive statistics strip."
|
"purpose": "Present a compact responsive strip of key facts, counts, performance indicators, or trust signals."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Stepper",
|
"name": "Stepper",
|
||||||
@@ -482,7 +479,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Tabs",
|
"name": "Tabs",
|
||||||
"category": "navigation",
|
"category": "navigation",
|
||||||
"purpose": "Theme-aware, responsive tabs component."
|
"purpose": "Switch between related responsive content panels with horizontal or vertical orientation and selection events."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Textarea",
|
"name": "Textarea",
|
||||||
@@ -491,13 +488,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "TextLink",
|
"name": "TextLink",
|
||||||
"category": "layout",
|
"category": "marketing",
|
||||||
"purpose": "Styled inline action link with icons, arrows, external state, and disabled handling."
|
"purpose": "Render an accessible text action with optional icon, arrow, underline, external state, and semantic styling."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Timeline",
|
"name": "Timeline",
|
||||||
"category": "base",
|
"category": "base",
|
||||||
"purpose": "Theme-aware, responsive timeline component."
|
"purpose": "Present responsive chronological activity, milestones, or workflow status with rich item metadata."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "TimePicker",
|
"name": "TimePicker",
|
||||||
@@ -522,13 +519,12 @@
|
|||||||
{
|
{
|
||||||
"name": "TogglePassword",
|
"name": "TogglePassword",
|
||||||
"category": "advanced-forms",
|
"category": "advanced-forms",
|
||||||
"purpose": "Accessible password field with optional show and hide controls.",
|
"purpose": "Accessible password field with optional show and hide controls."
|
||||||
"events": ["input", "change", "toggle"]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Tooltip",
|
"name": "Tooltip",
|
||||||
"category": "overlays",
|
"category": "overlays",
|
||||||
"purpose": "Theme-aware, responsive tooltip component."
|
"purpose": "Show concise accessible contextual help on hover, focus, click, or controlled open state."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "TreeView",
|
"name": "TreeView",
|
||||||
@@ -538,7 +534,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Typography",
|
"name": "Typography",
|
||||||
"category": "layout",
|
"category": "layout",
|
||||||
"purpose": "Theme-aware, responsive typography component."
|
"purpose": "Apply consistent readable responsive typography, widths, columns, spacing, and editorial hierarchy."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "WysiwygEditor",
|
"name": "WysiwygEditor",
|
||||||
|
|||||||
+5605
-1752
File diff suppressed because it is too large
Load Diff
@@ -1,52 +1,55 @@
|
|||||||
component Accordion {
|
component Accordion {
|
||||||
props {
|
outputs {
|
||||||
size = "default"
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
color = "primary"
|
open(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
variant = "default"
|
close(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
class = ""
|
|
||||||
|
|
||||||
id = "accordion"
|
|
||||||
items = []
|
|
||||||
defaultOpen = []
|
|
||||||
multiple = false
|
|
||||||
alwaysOpen = false
|
|
||||||
disabled = false
|
|
||||||
|
|
||||||
indicator = "plus"
|
|
||||||
indicatorPosition = "start"
|
|
||||||
showIndicator = true
|
|
||||||
bordered = false
|
|
||||||
separated = false
|
|
||||||
flush = false
|
|
||||||
contentItalic = false
|
|
||||||
|
|
||||||
@event change = function
|
|
||||||
@event open = function
|
|
||||||
@event close = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "default"
|
||||||
|
class: string = ""
|
||||||
|
|
||||||
|
id: string = "accordion"
|
||||||
|
items: unknown[] = []
|
||||||
|
defaultOpen: unknown[] = []
|
||||||
|
multiple: boolean = false
|
||||||
|
alwaysOpen: boolean = false
|
||||||
|
disabled: boolean = false
|
||||||
|
|
||||||
|
indicator: string = "plus"
|
||||||
|
indicatorPosition: string = "start"
|
||||||
|
showIndicator: boolean = true
|
||||||
|
bordered: boolean = false
|
||||||
|
separated: boolean = false
|
||||||
|
flush: boolean = false
|
||||||
|
contentItalic: boolean = false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
state openValues = defaultOpen
|
state openValues = defaultOpen
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function itemValue(item, index) {
|
shared function itemValue(item, index) {
|
||||||
return item.value !== undefined && item.value !== ""
|
return item.value !== undefined && item.value !== ""
|
||||||
? String(item.value)
|
? String(item.value)
|
||||||
: String(index)
|
: String(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
function nestedValue(parent, parentIndex, item, index) {
|
shared function nestedValue(parent, parentIndex, item, index) {
|
||||||
return itemValue(parent, parentIndex) + "." + itemValue(item, index)
|
return itemValue(parent, parentIndex) + "." + itemValue(item, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isOpen(value) {
|
shared function isOpen(value) {
|
||||||
return openValues.includes(value)
|
return openValues.includes(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function allowsMultiple() {
|
shared function allowsMultiple() {
|
||||||
return multiple || alwaysOpen
|
return multiple || alwaysOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispatchAccordionEvent(sourceEvent, eventName, value, item, root, customEvent) {
|
client function dispatchAccordionEvent(sourceEvent, eventName, value, item, root, customEvent) {
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-accordion]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-accordion]")
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
@@ -64,7 +67,7 @@ component Accordion {
|
|||||||
root.dispatchEvent(customEvent)
|
root.dispatchEvent(customEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleItem(sourceEvent, value, item, wasOpen) {
|
client function toggleItem(sourceEvent, value, item, wasOpen) {
|
||||||
if (disabled || item.disabled) {
|
if (disabled || item.disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
component AdvancedDatePicker {
|
component AdvancedDatePicker {
|
||||||
|
outputs {
|
||||||
|
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
open(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
close(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
clear(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event open = function
|
title: string = "Advanced Date Picker"
|
||||||
@event close = function
|
description: string = ""
|
||||||
@event clear = function
|
items: unknown[] = []
|
||||||
size = "default"
|
variant: string = "default"
|
||||||
color = "primary"
|
class: string = ""
|
||||||
title = "Advanced Date Picker"
|
|
||||||
description = ""
|
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--advanced-date-picker wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--advanced-date-picker wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
component AdvancedRangeSlider {
|
component AdvancedRangeSlider {
|
||||||
|
outputs {
|
||||||
|
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
start(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
end(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event start = function
|
title: string = "Advanced Range Slider"
|
||||||
@event end = function
|
description: string = ""
|
||||||
size = "default"
|
items: unknown[] = []
|
||||||
color = "primary"
|
variant: string = "default"
|
||||||
title = "Advanced Range Slider"
|
class: string = ""
|
||||||
description = ""
|
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--advanced-range-slider wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--advanced-range-slider wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,82 +1,85 @@
|
|||||||
component AdvancedSelect {
|
component AdvancedSelect {
|
||||||
|
outputs {
|
||||||
|
search(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
clear(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
open(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
close(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
load(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
label = "Advanced Select"
|
label: string = "Advanced Select"
|
||||||
name = ""
|
name: string = ""
|
||||||
value = ""
|
value: string = ""
|
||||||
values = []
|
values: unknown[] = []
|
||||||
options = []
|
options: unknown[] = []
|
||||||
groups = []
|
groups: unknown[] = []
|
||||||
placeholder = "Select an option"
|
placeholder: string = "Select an option"
|
||||||
placeholderIcon = ""
|
placeholderIcon: string = ""
|
||||||
searchPlaceholder = "Search options…"
|
searchPlaceholder: string = "Search options…"
|
||||||
multiple = false
|
multiple: boolean = false
|
||||||
searchable = true
|
searchable: boolean = true
|
||||||
defaultOpen = false
|
defaultOpen: boolean = false
|
||||||
clearable = true
|
clearable: boolean = true
|
||||||
allowEmpty = true
|
allowEmpty: boolean = true
|
||||||
tags = false
|
tags: boolean = false
|
||||||
disabled = false
|
disabled: boolean = false
|
||||||
required = false
|
required: boolean = false
|
||||||
invalid = false
|
invalid: boolean = false
|
||||||
validationMessage = ""
|
validationMessage: string = ""
|
||||||
helpText = ""
|
helpText: string = ""
|
||||||
loading = false
|
loading: boolean = false
|
||||||
loadingLabel = "Loading options…"
|
loadingLabel: string = "Loading options…"
|
||||||
emptyLabel = "No options found"
|
emptyLabel: string = "No options found"
|
||||||
selectedOptionsLabel = "Selected options"
|
selectedOptionsLabel: string = "Selected options"
|
||||||
clearLabel = "Clear selection"
|
clearLabel: string = "Clear selection"
|
||||||
createLabel = "Create"
|
createLabel: string = "Create"
|
||||||
loadMoreLabel = "Load more"
|
loadMoreLabel: string = "Load more"
|
||||||
searchMode = "contains"
|
searchMode: string = "contains"
|
||||||
searchFields = "label,description"
|
searchFields: string = "label,description"
|
||||||
minSearchLength = 0
|
minSearchLength: number = 0
|
||||||
searchResultLimit = 0
|
searchResultLimit: number = 0
|
||||||
maxSelections = 0
|
maxSelections: number = 0
|
||||||
showCounter = false
|
showCounter: boolean = false
|
||||||
counterTemplate = "{selected} selected"
|
counterTemplate: string = "{selected} selected"
|
||||||
optionTemplate = "default"
|
optionTemplate: string = "default"
|
||||||
selectedTemplate = "default"
|
selectedTemplate: string = "default"
|
||||||
closeOnSelect = true
|
closeOnSelect: boolean = true
|
||||||
scrollToSelected = true
|
scrollToSelected: boolean = true
|
||||||
fixed = false
|
fixed: boolean = false
|
||||||
placement = "bottom"
|
placement: string = "bottom"
|
||||||
remote = false
|
remote: boolean = false
|
||||||
remoteUrl = ""
|
remoteUrl: string = ""
|
||||||
remoteQueryParam = "q"
|
remoteQueryParam: string = "q"
|
||||||
remoteDebounce = 250
|
remoteDebounce: number = 250
|
||||||
remoteAutoLoad = true
|
remoteAutoLoad: boolean = true
|
||||||
infinite = false
|
infinite: boolean = false
|
||||||
hasMore = false
|
hasMore: boolean = false
|
||||||
page = 1
|
page: number = 1
|
||||||
class = ""
|
class: string = ""
|
||||||
@event search = function
|
|
||||||
@event select = function
|
|
||||||
@event change = function
|
|
||||||
@event clear = function
|
|
||||||
@event open = function
|
|
||||||
@event close = function
|
|
||||||
@event load = function
|
|
||||||
@event error = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state open = defaultOpen
|
state open = defaultOpen
|
||||||
state query = ""
|
state query: string = ""
|
||||||
state activeIndex = -1
|
state activeIndex: number = -1
|
||||||
state selectedValue = value
|
state selectedValue = value
|
||||||
state selectedValues = values
|
state selectedValues = values
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function allOptions() {
|
shared function allOptions() {
|
||||||
return [...groups.flatMap((group) => group.options || []), ...options]
|
return [...groups.flatMap((group) => group.options || []), ...options]
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchableText(option) {
|
shared function searchableText(option) {
|
||||||
return ((option.label || "") + " " + (option.description || "")).toLowerCase()
|
return ((option.label || "") + " " + (option.description || "")).toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
function matches(option) {
|
shared function matches(option) {
|
||||||
if (!query || query.length < Number(minSearchLength || 0)) {
|
if (!query || query.length < Number(minSearchLength || 0)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -89,22 +92,22 @@ component AdvancedSelect {
|
|||||||
return searchableText(option).includes(query.toLowerCase())
|
return searchableText(option).includes(query.toLowerCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
function matchingOptions(list) {
|
shared function matchingOptions(list) {
|
||||||
return list.filter((option) => matches(option))
|
return list.filter((option) => matches(option))
|
||||||
}
|
}
|
||||||
|
|
||||||
function visibleOptions(list) {
|
shared function visibleOptions(list) {
|
||||||
if (searchResultLimit > 0) {
|
if (searchResultLimit > 0) {
|
||||||
return matchingOptions(list).slice(0, Number(searchResultLimit))
|
return matchingOptions(list).slice(0, Number(searchResultLimit))
|
||||||
}
|
}
|
||||||
return matchingOptions(list)
|
return matchingOptions(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
function flatVisibleOptions() {
|
shared function flatVisibleOptions() {
|
||||||
return visibleOptions(allOptions())
|
return visibleOptions(allOptions())
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSelected(option) {
|
shared function isSelected(option) {
|
||||||
return (
|
return (
|
||||||
multiple
|
multiple
|
||||||
? selectedValues.includes(option.value)
|
? selectedValues.includes(option.value)
|
||||||
@@ -112,15 +115,15 @@ component AdvancedSelect {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectedOptions() {
|
shared function selectedOptions() {
|
||||||
return allOptions().filter((option) => isSelected(option))
|
return allOptions().filter((option) => isSelected(option))
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectedCount() {
|
shared function selectedCount() {
|
||||||
return multiple ? selectedValues.length : selectedValue ? 1 : 0
|
return multiple ? selectedValues.length : selectedValue ? 1 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function counterText() {
|
shared function counterText() {
|
||||||
return (
|
return (
|
||||||
maxSelections
|
maxSelections
|
||||||
? selectedCount() + " / " + maxSelections + " selected"
|
? selectedCount() + " / " + maxSelections + " selected"
|
||||||
@@ -128,7 +131,7 @@ component AdvancedSelect {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectedText() {
|
shared function selectedText() {
|
||||||
return (
|
return (
|
||||||
multiple
|
multiple
|
||||||
? selectedValues.join(", ")
|
? selectedValues.join(", ")
|
||||||
@@ -138,11 +141,11 @@ component AdvancedSelect {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function triggerText() {
|
shared function triggerText() {
|
||||||
return selectedCount() ? selectedText() : placeholder
|
return selectedCount() ? selectedText() : placeholder
|
||||||
}
|
}
|
||||||
|
|
||||||
function canSelect(option) {
|
shared function canSelect(option) {
|
||||||
if (option.disabled) {
|
if (option.disabled) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -155,7 +158,7 @@ component AdvancedSelect {
|
|||||||
return selectedCount() < maxSelections
|
return selectedCount() < maxSelections
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseSingle(option) {
|
shared function chooseSingle(option) {
|
||||||
if (!canSelect(option)) {
|
if (!canSelect(option)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -166,7 +169,7 @@ component AdvancedSelect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseMultiple(option) {
|
shared function chooseMultiple(option) {
|
||||||
if (!canSelect(option)) {
|
if (!canSelect(option)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -178,7 +181,7 @@ component AdvancedSelect {
|
|||||||
query = ""
|
query = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseOption(option) {
|
shared function chooseOption(option) {
|
||||||
if (multiple) {
|
if (multiple) {
|
||||||
chooseMultiple(option)
|
chooseMultiple(option)
|
||||||
return
|
return
|
||||||
@@ -186,7 +189,7 @@ component AdvancedSelect {
|
|||||||
chooseSingle(option)
|
chooseSingle(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearSelection(event) {
|
client function clearSelection(event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
selectedValue = ""
|
selectedValue = ""
|
||||||
selectedValues = []
|
selectedValues = []
|
||||||
@@ -194,7 +197,7 @@ component AdvancedSelect {
|
|||||||
open = false
|
open = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
shared function toggle() {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -202,14 +205,14 @@ component AdvancedSelect {
|
|||||||
activeIndex = open && flatVisibleOptions().length ? 0 : -1;
|
activeIndex = open && flatVisibleOptions().length ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveActive(direction) {
|
shared function moveActive(direction) {
|
||||||
if (!flatVisibleOptions().length) {
|
if (!flatVisibleOptions().length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
activeIndex = (activeIndex + direction + flatVisibleOptions().length) % flatVisibleOptions().length
|
activeIndex = (activeIndex + direction + flatVisibleOptions().length) % flatVisibleOptions().length
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeydown(event) {
|
client function handleKeydown(event) {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -243,7 +246,7 @@ component AdvancedSelect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function optionIndex(option) {
|
shared function optionIndex(option) {
|
||||||
return flatVisibleOptions().findIndex((item) => item.value === option.value)
|
return flatVisibleOptions().findIndex((item) => item.value === option.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,36 @@
|
|||||||
component AvatarGroup {
|
component AvatarGroup {
|
||||||
props {
|
outputs {
|
||||||
items = []
|
overflow(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
size = "md"
|
|
||||||
color = "primary"
|
|
||||||
variant = "solid"
|
|
||||||
shape = "circle"
|
|
||||||
layout = "stack"
|
|
||||||
maxVisible = 4
|
|
||||||
columns = 3
|
|
||||||
borderColor = ""
|
|
||||||
showTooltips = true
|
|
||||||
overflowLabel = "Show remaining members"
|
|
||||||
class = ""
|
|
||||||
|
|
||||||
@event overflow = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state overflowOpen = false
|
props {
|
||||||
|
items: unknown[] = []
|
||||||
|
size: string = "md"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "solid"
|
||||||
|
shape: string = "circle"
|
||||||
|
layout: string = "stack"
|
||||||
|
maxVisible: number = 4
|
||||||
|
columns: number = 3
|
||||||
|
borderColor: string = ""
|
||||||
|
showTooltips: boolean = true
|
||||||
|
overflowLabel: string = "Show remaining members"
|
||||||
|
class: string = ""
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
state overflowOpen: boolean = false
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function visibleMembers() {
|
shared function visibleMembers() {
|
||||||
return items.slice(0, Number(maxVisible))
|
return items.slice(0, Number(maxVisible))
|
||||||
}
|
}
|
||||||
|
|
||||||
function hiddenMembers() {
|
shared function hiddenMembers() {
|
||||||
return items.slice(Number(maxVisible))
|
return items.slice(Number(maxVisible))
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleOverflow(sourceEvent, root, customEvent) {
|
client function toggleOverflow(sourceEvent, root, customEvent) {
|
||||||
overflowOpen = !overflowOpen
|
overflowOpen = !overflowOpen
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-avatar-group]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-avatar-group]")
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
component Blockquote {
|
component Blockquote {
|
||||||
props {
|
props {
|
||||||
quote = "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."
|
quote: string = "I just wanted to say that I'm very happy with my purchase so far. The documentation is outstanding - clear and detailed."
|
||||||
citation = ""
|
citation: string = ""
|
||||||
citationTitle = ""
|
citationTitle: string = ""
|
||||||
citationUrl = ""
|
citationUrl: string = ""
|
||||||
avatarSrc = ""
|
avatarSrc: string = ""
|
||||||
avatarAlt = ""
|
avatarAlt: string = ""
|
||||||
size = "md"
|
size: string = "md"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
align = "left"
|
align: string = "left"
|
||||||
variant = "default"
|
variant: string = "default"
|
||||||
quoteMark = true
|
quoteMark: boolean = true
|
||||||
italic = true
|
italic: boolean = true
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,19 +1,323 @@
|
|||||||
component Breadcrumb {
|
component Breadcrumb {
|
||||||
props {
|
outputs {
|
||||||
@event navigate = function
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
@event click = function
|
|
||||||
size = "default"
|
|
||||||
color = "primary"
|
|
||||||
label = "Breadcrumb"
|
|
||||||
items = []
|
|
||||||
active = ""
|
|
||||||
orientation = "horizontal"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
label: string = "Breadcrumb"
|
||||||
|
items: unknown[] = []
|
||||||
|
active: string = ""
|
||||||
|
separator: string = "chevron"
|
||||||
|
showHome: boolean = false
|
||||||
|
homeLabel: string = "Home"
|
||||||
|
homeHref: string = "/"
|
||||||
|
homeIcon: string = "icon-[lucide--house]"
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "minimal"
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--breadcrumb wire-next--{orientation} {class}" aria-label="{label}">
|
<nav
|
||||||
{#each items as item}<a href="{item.href}" aria-current="{item.value === active ? 'page' : ''}">{item.label}</a>{/each}
|
{...attrs}
|
||||||
<slot />
|
data-ui-component="Breadcrumb"
|
||||||
|
data-size='{size}'
|
||||||
|
data-color='{color}'
|
||||||
|
data-variant='{variant}'
|
||||||
|
aria-label='{label}'
|
||||||
|
class='wire-breadcrumb {class}'
|
||||||
|
>
|
||||||
|
<ol class="wire-breadcrumb__list">
|
||||||
|
{#if showHome}
|
||||||
|
<li class="wire-breadcrumb__item wire-breadcrumb__item--home">
|
||||||
|
<a
|
||||||
|
href='{homeHref || "/"}'
|
||||||
|
class="wire-breadcrumb__link wire-breadcrumb__home"
|
||||||
|
@click='event.currentTarget.dispatchEvent(new CustomEvent("select", { bubbles: true, detail: { item: { label: homeLabel, href: homeHref || "/", value: "home" }, itemIndex: -1 } }))'
|
||||||
|
>
|
||||||
|
{#if homeIcon === "icon-[lucide--house]"}
|
||||||
|
<span class="icon-[lucide--house] wire-breadcrumb__icon" aria-hidden="true"></span>
|
||||||
|
{:else if homeIcon}
|
||||||
|
<span class='{homeIcon} wire-breadcrumb__icon' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<span class="wire-breadcrumb__home-label">{homeLabel}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#each items as item, itemIndex}
|
||||||
|
<li
|
||||||
|
class="wire-breadcrumb__item"
|
||||||
|
data-current='{item.active || item.current || (active && active === (item.value || item.label || item.title)) || (!active && itemIndex === items.length - 1) ? "true" : "false"}'
|
||||||
|
>
|
||||||
|
{#if showHome || itemIndex > 0}
|
||||||
|
<span class="wire-breadcrumb__separator" aria-hidden="true">
|
||||||
|
{#if separator === "slash"}
|
||||||
|
<span>/</span>
|
||||||
|
{:else if separator === "dot"}
|
||||||
|
<span>•</span>
|
||||||
|
{:else if separator === "arrow"}
|
||||||
|
<span>→</span>
|
||||||
|
{:else}
|
||||||
|
<span class="icon-[lucide--chevron-right] wire-breadcrumb__separator-icon"></span>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if item.href && !item.disabled && !(item.active || item.current || (active && active === (item.value || item.label || item.title)) || (!active && itemIndex === items.length - 1))}
|
||||||
|
<a
|
||||||
|
href='{item.href}'
|
||||||
|
target='{item.target || ""}'
|
||||||
|
rel='{item.external ? "noopener noreferrer" : (item.rel || "")}'
|
||||||
|
class="wire-breadcrumb__link"
|
||||||
|
@click='event.currentTarget.dispatchEvent(new CustomEvent("select", { bubbles: true, detail: { item: item, itemIndex: itemIndex } }))'
|
||||||
|
>
|
||||||
|
{#if item.icon}
|
||||||
|
<span class='{item.icon} wire-breadcrumb__icon' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<span class="wire-breadcrumb__label">{item.label || item.title}</span>
|
||||||
|
|
||||||
|
{#if item.external}
|
||||||
|
<span class="icon-[lucide--arrow-up-right] wire-breadcrumb__external" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<span
|
||||||
|
class="wire-breadcrumb__current"
|
||||||
|
aria-current='{item.active || item.current || (active && active === (item.value || item.label || item.title)) || (!active && itemIndex === items.length - 1) ? "page" : ""}'
|
||||||
|
aria-disabled='{item.disabled ? "true" : "false"}'
|
||||||
|
>
|
||||||
|
{#if item.icon}
|
||||||
|
<span class='{item.icon} wire-breadcrumb__icon' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<span class="wire-breadcrumb__label">{item.label || item.title}</span>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style {
|
||||||
|
.wire-breadcrumb {
|
||||||
|
--breadcrumb-accent: var(--wire-color-primary);
|
||||||
|
--breadcrumb-soft: var(--wire-color-primary-soft);
|
||||||
|
--breadcrumb-muted: var(--wire-color-primary-muted);
|
||||||
|
--breadcrumb-text: var(--wire-color-primary-text);
|
||||||
|
|
||||||
|
min-width: 0;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-color="secondary"] {
|
||||||
|
--breadcrumb-accent: var(--wire-color-secondary);
|
||||||
|
--breadcrumb-soft: var(--wire-color-secondary-soft);
|
||||||
|
--breadcrumb-muted: var(--wire-color-secondary-muted);
|
||||||
|
--breadcrumb-text: var(--wire-color-secondary-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-color="info"] {
|
||||||
|
--breadcrumb-accent: var(--wire-color-info);
|
||||||
|
--breadcrumb-soft: var(--wire-color-info-soft);
|
||||||
|
--breadcrumb-muted: var(--wire-color-info-muted);
|
||||||
|
--breadcrumb-text: var(--wire-color-info-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-color="success"] {
|
||||||
|
--breadcrumb-accent: var(--wire-color-success);
|
||||||
|
--breadcrumb-soft: var(--wire-color-success-soft);
|
||||||
|
--breadcrumb-muted: var(--wire-color-success-muted);
|
||||||
|
--breadcrumb-text: var(--wire-color-success-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-color="warning"] {
|
||||||
|
--breadcrumb-accent: var(--wire-color-warning);
|
||||||
|
--breadcrumb-soft: var(--wire-color-warning-soft);
|
||||||
|
--breadcrumb-muted: var(--wire-color-warning-muted);
|
||||||
|
--breadcrumb-text: var(--wire-color-warning-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-color="danger"] {
|
||||||
|
--breadcrumb-accent: var(--wire-color-danger);
|
||||||
|
--breadcrumb-soft: var(--wire-color-danger-soft);
|
||||||
|
--breadcrumb-muted: var(--wire-color-danger-muted);
|
||||||
|
--breadcrumb-text: var(--wire-color-danger-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-variant="soft"] {
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 0.45rem 0.65rem;
|
||||||
|
background: var(--breadcrumb-soft);
|
||||||
|
border: 1px solid var(--breadcrumb-muted);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-variant="outline"] {
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 0.45rem 0.65rem;
|
||||||
|
background: var(--wire-color-surface-raised);
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
box-shadow: var(--wire-shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-variant="contrast"] {
|
||||||
|
color: rgba(255, 255, 255, 0.78);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__list {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0;
|
||||||
|
min-width: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
list-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__list::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__item {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 0;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__separator {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-inline: 0.45rem;
|
||||||
|
color: var(--wire-color-text-subtle);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
opacity: 0.72;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__separator-icon {
|
||||||
|
width: 0.9rem;
|
||||||
|
height: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__link,
|
||||||
|
.wire-breadcrumb__current {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 2rem;
|
||||||
|
padding: 0.25rem 0.4rem;
|
||||||
|
border-radius: 0.55rem;
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
line-height: 1.25rem;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-size="sm"] .wire-breadcrumb__link,
|
||||||
|
.wire-breadcrumb[data-size="sm"] .wire-breadcrumb__current {
|
||||||
|
min-height: 1.75rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-size="lg"] .wire-breadcrumb__link,
|
||||||
|
.wire-breadcrumb[data-size="lg"] .wire-breadcrumb__current {
|
||||||
|
min-height: 2.25rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__link {
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-weight: 600;
|
||||||
|
transition:
|
||||||
|
color 160ms ease,
|
||||||
|
background 160ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__link:hover {
|
||||||
|
color: var(--breadcrumb-accent);
|
||||||
|
background: var(--breadcrumb-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__link:focus-visible {
|
||||||
|
color: var(--breadcrumb-accent);
|
||||||
|
outline: 2px solid var(--breadcrumb-accent);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__current {
|
||||||
|
max-width: 22rem;
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
font-weight: 750;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__item[data-current="true"] .wire-breadcrumb__current {
|
||||||
|
color: var(--breadcrumb-text);
|
||||||
|
background: var(--breadcrumb-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__current[aria-disabled="true"] {
|
||||||
|
opacity: 0.58;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__icon,
|
||||||
|
.wire-breadcrumb__external {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 0.95rem;
|
||||||
|
height: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__home {
|
||||||
|
color: var(--breadcrumb-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__label {
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__link,
|
||||||
|
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__current,
|
||||||
|
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__home {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__link:hover,
|
||||||
|
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__item[data-current="true"] .wire-breadcrumb__current {
|
||||||
|
color: #ffffff;
|
||||||
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb[data-variant="contrast"] .wire-breadcrumb__separator {
|
||||||
|
color: rgba(255, 255, 255, 0.62);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
.wire-breadcrumb__home-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-breadcrumb__current {
|
||||||
|
max-width: 13rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.wire-breadcrumb__link {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,38 @@
|
|||||||
component ButtonGroup {
|
component ButtonGroup {
|
||||||
|
outputs {
|
||||||
|
click(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
select(payload: { value: string | number | boolean | null | object; previousValue: string | number | boolean | null | object; item: string | number | boolean | null | object; index: number })
|
||||||
|
change(payload: { value: string | number | boolean | null | object; previousValue: string | number | boolean | null | object; item: string | number | boolean | null | object; index: number })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event click = function
|
items: unknown[] = []
|
||||||
@event select = function
|
value: string = ""
|
||||||
@event change = function
|
size: string = "md"
|
||||||
items = []
|
color: string = "primary"
|
||||||
value = ""
|
variant: string = "default"
|
||||||
size = "md"
|
orientation: string = "horizontal"
|
||||||
color = "primary"
|
responsive: boolean = false
|
||||||
variant = "default"
|
attached: boolean = true
|
||||||
orientation = "horizontal"
|
selectable: boolean = false
|
||||||
responsive = false
|
toolbar: boolean = false
|
||||||
attached = true
|
disabled: boolean = false
|
||||||
selectable = false
|
ariaLabel: string = "Button group"
|
||||||
toolbar = false
|
class: string = ""
|
||||||
disabled = false
|
|
||||||
ariaLabel = "Button group"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state selectedValue = value
|
state selectedValue = value
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function itemValue(item, index) {
|
shared function itemValue(item, index) {
|
||||||
return item.value || item.label || String(index)
|
return item.value || item.label || String(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectItem(item, index) {
|
client function selectItem(item, index) {
|
||||||
previousValue = selectedValue
|
previousValue = selectedValue
|
||||||
nextValue = itemValue(item, index)
|
nextValue = itemValue(item, index)
|
||||||
|
|
||||||
$emit("select", {
|
output.select({
|
||||||
value: nextValue,
|
value: nextValue,
|
||||||
previousValue: previousValue,
|
previousValue: previousValue,
|
||||||
item: item,
|
item: item,
|
||||||
@@ -38,7 +41,7 @@ component ButtonGroup {
|
|||||||
|
|
||||||
if (selectable && previousValue !== nextValue) {
|
if (selectable && previousValue !== nextValue) {
|
||||||
selectedValue = nextValue
|
selectedValue = nextValue
|
||||||
$emit("change", {
|
output.change({
|
||||||
value: nextValue,
|
value: nextValue,
|
||||||
previousValue: previousValue,
|
previousValue: previousValue,
|
||||||
item: item,
|
item: item,
|
||||||
|
|||||||
@@ -1,53 +1,56 @@
|
|||||||
// Interactive, hydration-safe content carousel.
|
// Interactive, hydration-safe content carousel.
|
||||||
component Carousel {
|
component Carousel {
|
||||||
|
outputs {
|
||||||
|
initialize(payload: { index: number; count: number })
|
||||||
|
change(payload: { index: number; previousIndex: number; item: string | number | boolean | null | object; reason: string | boolean })
|
||||||
|
previous(payload: { index: number; previousIndex: number; item: string | number | boolean | null | object })
|
||||||
|
next(payload: { index: number; previousIndex: number; item: string | number | boolean | null | object })
|
||||||
|
play(payload: { index: number; interval: number })
|
||||||
|
pause(payload: { index: number })
|
||||||
|
reachStart(payload: { index: number })
|
||||||
|
reachEnd(payload: { index: number })
|
||||||
|
dragStart(payload: { index: number; x: null })
|
||||||
|
dragEnd(payload: { index: number; distance: number })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event initialize = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event previous = function
|
title: string = ""
|
||||||
@event next = function
|
description: string = ""
|
||||||
@event play = function
|
items: unknown[] = []
|
||||||
@event pause = function
|
activeIndex: number = 0
|
||||||
@event reachStart = function
|
slidesPerView: number = 1
|
||||||
@event reachEnd = function
|
gap: string = "0.75rem"
|
||||||
@event dragStart = function
|
showPagination: boolean = false
|
||||||
@event dragEnd = function
|
isAutoPlay: boolean = false
|
||||||
size = "default"
|
autoplayInterval: number = 4000
|
||||||
color = "primary"
|
isInfiniteLoop: boolean = false
|
||||||
title = ""
|
isRTL: boolean = false
|
||||||
description = ""
|
isCentered: boolean = false
|
||||||
items = []
|
isDraggable: boolean = false
|
||||||
activeIndex = 0
|
isAutoHeight: boolean = false
|
||||||
slidesPerView = 1
|
isSnap: boolean = false
|
||||||
gap = "0.75rem"
|
showCounter: boolean = false
|
||||||
showPagination = false
|
thumbnails: string = "none"
|
||||||
isAutoPlay = false
|
ariaLabel: string = "Content carousel"
|
||||||
autoplayInterval = 4000
|
variant: string = "default"
|
||||||
isInfiniteLoop = false
|
class: string = ""
|
||||||
isRTL = false
|
|
||||||
isCentered = false
|
|
||||||
isDraggable = false
|
|
||||||
isAutoHeight = false
|
|
||||||
isSnap = false
|
|
||||||
showCounter = false
|
|
||||||
thumbnails = "none"
|
|
||||||
ariaLabel = "Content carousel"
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state currentIndex = activeIndex
|
state currentIndex = activeIndex
|
||||||
state playing = false
|
state playing: boolean = false
|
||||||
state dragOrigin = null
|
state dragOrigin = null
|
||||||
state dragOffset = 0
|
state dragOffset: number = 0
|
||||||
state autoplayTimer = null
|
state autoplayTimer = null
|
||||||
state carouselRoot = null
|
state carouselRoot = null
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function slideCount() {
|
shared function slideCount() {
|
||||||
return items.length
|
return items.length
|
||||||
}
|
}
|
||||||
|
|
||||||
function maximumIndex(count, visible) {
|
shared function maximumIndex(count, visible) {
|
||||||
count = slideCount()
|
count = slideCount()
|
||||||
visible = Math.max(1, Number(slidesPerView) || 1)
|
visible = Math.max(1, Number(slidesPerView) || 1)
|
||||||
if (isCentered || isSnap) {
|
if (isCentered || isSnap) {
|
||||||
@@ -56,7 +59,7 @@ component Carousel {
|
|||||||
return Math.max(0, count - visible)
|
return Math.max(0, count - visible)
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizedIndex(index, maximum) {
|
shared function normalizedIndex(index, maximum) {
|
||||||
maximum = maximumIndex()
|
maximum = maximumIndex()
|
||||||
if (slideCount() === 0) {
|
if (slideCount() === 0) {
|
||||||
return 0
|
return 0
|
||||||
@@ -72,7 +75,7 @@ component Carousel {
|
|||||||
return Math.max(0, Math.min(index, maximum))
|
return Math.max(0, Math.min(index, maximum))
|
||||||
}
|
}
|
||||||
|
|
||||||
function rememberRoot(sourceEvent, root) {
|
client function rememberRoot(sourceEvent, root) {
|
||||||
if (!sourceEvent || !sourceEvent.currentTarget) {
|
if (!sourceEvent || !sourceEvent.currentTarget) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -82,7 +85,7 @@ component Carousel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncNavigation(sourceEvent, index, root, viewport, slides, slide, thumbnails, thumbnail, rail) {
|
client function syncNavigation(sourceEvent, index, root, viewport, slides, slide, thumbnails, thumbnail, rail) {
|
||||||
rememberRoot(sourceEvent)
|
rememberRoot(sourceEvent)
|
||||||
root = carouselRoot
|
root = carouselRoot
|
||||||
if (!root) {
|
if (!root) {
|
||||||
@@ -111,7 +114,7 @@ component Carousel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSnapScroll(sourceEvent, slides, viewport, viewportCenter, closestIndex, closestDistance, slide, slideCenter, distance, previousIndex) {
|
client function handleSnapScroll(sourceEvent, slides, viewport, viewportCenter, closestIndex, closestDistance, slide, slideCenter, distance, previousIndex) {
|
||||||
if (!isSnap) {
|
if (!isSnap) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -133,7 +136,7 @@ component Carousel {
|
|||||||
if (closestIndex !== currentIndex) {
|
if (closestIndex !== currentIndex) {
|
||||||
previousIndex = currentIndex
|
previousIndex = currentIndex
|
||||||
currentIndex = closestIndex
|
currentIndex = closestIndex
|
||||||
$emit("change", {
|
output.change({
|
||||||
index: currentIndex,
|
index: currentIndex,
|
||||||
previousIndex: previousIndex,
|
previousIndex: previousIndex,
|
||||||
item: items[currentIndex],
|
item: items[currentIndex],
|
||||||
@@ -152,7 +155,7 @@ component Carousel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectSlide(index, reason, sourceEvent, previousIndex) {
|
client function selectSlide(index, reason, sourceEvent, previousIndex) {
|
||||||
if (slideCount() === 0) {
|
if (slideCount() === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -162,41 +165,41 @@ component Carousel {
|
|||||||
if (previousIndex === currentIndex && reason !== "initialize") {
|
if (previousIndex === currentIndex && reason !== "initialize") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
$emit("change", {
|
output.change({
|
||||||
index: currentIndex,
|
index: currentIndex,
|
||||||
previousIndex: previousIndex,
|
previousIndex: previousIndex,
|
||||||
item: items[currentIndex],
|
item: items[currentIndex],
|
||||||
reason: reason || "select"
|
reason: reason || "select"
|
||||||
})
|
})
|
||||||
if (currentIndex === 0) {
|
if (currentIndex === 0) {
|
||||||
$emit("reachStart", { index: currentIndex })
|
output.reachStart({ index: currentIndex })
|
||||||
}
|
}
|
||||||
if (currentIndex === maximumIndex()) {
|
if (currentIndex === maximumIndex()) {
|
||||||
$emit("reachEnd", { index: currentIndex })
|
output.reachEnd({ index: currentIndex })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function previousSlide(sourceEvent, previousIndex) {
|
client function previousSlide(sourceEvent, previousIndex) {
|
||||||
previousIndex = currentIndex
|
previousIndex = currentIndex
|
||||||
selectSlide(currentIndex - 1, "previous", sourceEvent)
|
selectSlide(currentIndex - 1, "previous", sourceEvent)
|
||||||
$emit("previous", {
|
output.previous({
|
||||||
index: currentIndex,
|
index: currentIndex,
|
||||||
previousIndex: previousIndex,
|
previousIndex: previousIndex,
|
||||||
item: items[currentIndex]
|
item: items[currentIndex]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextSlide(sourceEvent, previousIndex) {
|
client function nextSlide(sourceEvent, previousIndex) {
|
||||||
previousIndex = currentIndex
|
previousIndex = currentIndex
|
||||||
selectSlide(currentIndex + 1, "next", sourceEvent)
|
selectSlide(currentIndex + 1, "next", sourceEvent)
|
||||||
$emit("next", {
|
output.next({
|
||||||
index: currentIndex,
|
index: currentIndex,
|
||||||
previousIndex: previousIndex,
|
previousIndex: previousIndex,
|
||||||
item: items[currentIndex]
|
item: items[currentIndex]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeydown(sourceEvent) {
|
client function handleKeydown(sourceEvent) {
|
||||||
if (sourceEvent.key === "ArrowLeft") {
|
if (sourceEvent.key === "ArrowLeft") {
|
||||||
sourceEvent.preventDefault()
|
sourceEvent.preventDefault()
|
||||||
if (isRTL) {
|
if (isRTL) {
|
||||||
@@ -223,7 +226,7 @@ component Carousel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function beginDrag(sourceEvent) {
|
client function beginDrag(sourceEvent) {
|
||||||
if (!isDraggable || isSnap) {
|
if (!isDraggable || isSnap) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -231,10 +234,10 @@ component Carousel {
|
|||||||
dragOrigin = sourceEvent.clientX
|
dragOrigin = sourceEvent.clientX
|
||||||
dragOffset = 0
|
dragOffset = 0
|
||||||
sourceEvent.currentTarget.setPointerCapture(sourceEvent.pointerId)
|
sourceEvent.currentTarget.setPointerCapture(sourceEvent.pointerId)
|
||||||
$emit("dragStart", { index: currentIndex, x: dragOrigin })
|
output.dragStart({ index: currentIndex, x: dragOrigin })
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveDrag(sourceEvent) {
|
client function moveDrag(sourceEvent) {
|
||||||
if (!isDraggable || isSnap || dragOrigin === null) {
|
if (!isDraggable || isSnap || dragOrigin === null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -242,12 +245,12 @@ component Carousel {
|
|||||||
dragOffset = sourceEvent.clientX - dragOrigin
|
dragOffset = sourceEvent.clientX - dragOrigin
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelDrag() {
|
shared function cancelDrag() {
|
||||||
dragOrigin = null
|
dragOrigin = null
|
||||||
dragOffset = 0
|
dragOffset = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function endDrag(sourceEvent, distance) {
|
client function endDrag(sourceEvent, distance) {
|
||||||
if (!isDraggable || isSnap || dragOrigin === null) {
|
if (!isDraggable || isSnap || dragOrigin === null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -262,13 +265,13 @@ component Carousel {
|
|||||||
previousSlide(sourceEvent)
|
previousSlide(sourceEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$emit("dragEnd", {
|
output.dragEnd({
|
||||||
index: currentIndex,
|
index: currentIndex,
|
||||||
distance: distance
|
distance: distance
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function advanceAutoplay() {
|
shared function advanceAutoplay() {
|
||||||
if (currentIndex >= maximumIndex()) {
|
if (currentIndex >= maximumIndex()) {
|
||||||
selectSlide(0, "autoplay")
|
selectSlide(0, "autoplay")
|
||||||
} else {
|
} else {
|
||||||
@@ -276,22 +279,22 @@ component Carousel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function startAutoplay() {
|
client function startAutoplay() {
|
||||||
if (!isAutoPlay || playing || slideCount() < 2) {
|
if (!isAutoPlay || playing || slideCount() < 2) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
playing = true
|
playing = true
|
||||||
autoplayTimer = setInterval(advanceAutoplay, Math.max(1000, Number(autoplayInterval)))
|
autoplayTimer = setInterval(advanceAutoplay, Math.max(1000, Number(autoplayInterval)))
|
||||||
$emit("play", { index: currentIndex, interval: autoplayInterval })
|
output.play({ index: currentIndex, interval: autoplayInterval })
|
||||||
}
|
}
|
||||||
|
|
||||||
function pauseAutoplay() {
|
client function pauseAutoplay() {
|
||||||
if (autoplayTimer) {
|
if (autoplayTimer) {
|
||||||
clearInterval(autoplayTimer)
|
clearInterval(autoplayTimer)
|
||||||
}
|
}
|
||||||
autoplayTimer = null
|
autoplayTimer = null
|
||||||
if (playing) {
|
if (playing) {
|
||||||
$emit("pause", { index: currentIndex })
|
output.pause({ index: currentIndex })
|
||||||
}
|
}
|
||||||
playing = false
|
playing = false
|
||||||
}
|
}
|
||||||
@@ -300,7 +303,7 @@ component Carousel {
|
|||||||
|
|
||||||
lifecycle {
|
lifecycle {
|
||||||
mount {
|
mount {
|
||||||
$emit("initialize", { index: currentIndex, count: slideCount() })
|
output.initialize({ index: currentIndex, count: slideCount() })
|
||||||
startAutoplay()
|
startAutoplay()
|
||||||
}
|
}
|
||||||
unmount {
|
unmount {
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
component Chart {
|
component Chart {
|
||||||
|
outputs {
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
dataPointClick(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
legendToggle(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event select = function
|
size: string = "default"
|
||||||
@event dataPointClick = function
|
color: string = "primary"
|
||||||
@event legendToggle = function
|
title: string = "Chart"
|
||||||
size = "default"
|
description: string = ""
|
||||||
color = "primary"
|
items: unknown[] = []
|
||||||
title = "Chart"
|
variant: string = "default"
|
||||||
description = ""
|
class: string = ""
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--chart wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--chart wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,56 +1,59 @@
|
|||||||
component ChatBubble {
|
component ChatBubble {
|
||||||
|
outputs {
|
||||||
|
action(payload: { action: boolean; item: string | number | boolean | null | object; index: number })
|
||||||
|
messageClick(payload: { item: string | number | boolean | null | object; index: number; direction: string })
|
||||||
|
avatarClick(payload: { item: string | number | boolean | null | object; index: number; direction: string })
|
||||||
|
linkClick(payload: { link: string | number | boolean | null | object; item: string | number | boolean | null | object; index: number })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event action = function
|
size: string = "default"
|
||||||
@event messageClick = function
|
color: string = "primary"
|
||||||
@event avatarClick = function
|
title: string = ""
|
||||||
@event linkClick = function
|
description: string = ""
|
||||||
size = "default"
|
items: unknown[] = []
|
||||||
color = "primary"
|
oneSided: boolean = false
|
||||||
title = ""
|
showAvatars: boolean = false
|
||||||
description = ""
|
showMetadata: boolean = false
|
||||||
items = []
|
ariaLabel: string = "Conversation"
|
||||||
oneSided = false
|
variant: string = "default"
|
||||||
showAvatars = false
|
class: string = ""
|
||||||
showMetadata = false
|
|
||||||
ariaLabel = "Conversation"
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function messageDirection(item) {
|
shared function messageDirection(item) {
|
||||||
return item.direction === "outgoing" ? "outgoing" : "incoming"
|
return item.direction === "outgoing" ? "outgoing" : "incoming"
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectMessage(item, index) {
|
client function selectMessage(item, index) {
|
||||||
$emit("messageClick", {
|
output.messageClick({
|
||||||
item: item,
|
item: item,
|
||||||
index: index,
|
index: index,
|
||||||
direction: messageDirection(item)
|
direction: messageDirection(item)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectAvatar(sourceEvent, item, index) {
|
client function selectAvatar(sourceEvent, item, index) {
|
||||||
sourceEvent.stopPropagation()
|
sourceEvent.stopPropagation()
|
||||||
$emit("avatarClick", {
|
output.avatarClick({
|
||||||
item: item,
|
item: item,
|
||||||
index: index,
|
index: index,
|
||||||
direction: messageDirection(item)
|
direction: messageDirection(item)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectLink(sourceEvent, link, item, index) {
|
client function selectLink(sourceEvent, link, item, index) {
|
||||||
sourceEvent.stopPropagation()
|
sourceEvent.stopPropagation()
|
||||||
$emit("linkClick", {
|
output.linkClick({
|
||||||
link: link,
|
link: link,
|
||||||
item: item,
|
item: item,
|
||||||
index: index
|
index: index
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectAction(sourceEvent, item, index) {
|
client function selectAction(sourceEvent, item, index) {
|
||||||
sourceEvent.stopPropagation()
|
sourceEvent.stopPropagation()
|
||||||
$emit("action", {
|
output.action({
|
||||||
action: item.action || "retry",
|
action: item.action || "retry",
|
||||||
item: item,
|
item: item,
|
||||||
index: index
|
index: index
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
component Clipboard {
|
component Clipboard {
|
||||||
|
outputs {
|
||||||
|
copy(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
success(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event copy = function
|
size: string = "default"
|
||||||
@event success = function
|
color: string = "primary"
|
||||||
@event error = function
|
title: string = "Clipboard"
|
||||||
size = "default"
|
description: string = ""
|
||||||
color = "primary"
|
items: unknown[] = []
|
||||||
title = "Clipboard"
|
variant: string = "default"
|
||||||
description = ""
|
class: string = ""
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--clipboard wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--clipboard wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,26 +1,29 @@
|
|||||||
component Collapse {
|
component Collapse {
|
||||||
|
outputs {
|
||||||
|
toggle(payload: { index: number; item: string | number | boolean | null | object; open: boolean; openIndexes: number[] })
|
||||||
|
open(payload: { index: number; item: string | number | boolean | null | object })
|
||||||
|
close(payload: { index: number; item: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event toggle = function
|
size: string = "default"
|
||||||
@event open = function
|
color: string = "primary"
|
||||||
@event close = function
|
items: unknown[] = []
|
||||||
size = "default"
|
multiple: boolean = false
|
||||||
color = "primary"
|
mode: string = "panel"
|
||||||
items = []
|
initialOpenIndexes: unknown[] = []
|
||||||
multiple = false
|
ariaLabel: string = "Collapsible content"
|
||||||
mode = "panel"
|
class: string = ""
|
||||||
initialOpenIndexes = []
|
|
||||||
ariaLabel = "Collapsible content"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state openIndexes = initialOpenIndexes
|
state openIndexes = initialOpenIndexes
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function isOpen(index) {
|
shared function isOpen(index) {
|
||||||
return openIndexes.includes(index)
|
return openIndexes.includes(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleItem(index, item, opening) {
|
client function toggleItem(index, item, opening) {
|
||||||
if (item.disabled) {
|
if (item.disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -31,12 +34,12 @@ component Collapse {
|
|||||||
} else {
|
} else {
|
||||||
openIndexes = [index]
|
openIndexes = [index]
|
||||||
}
|
}
|
||||||
$emit("open", { index: index, item: item })
|
output.open({ index: index, item: item })
|
||||||
} else {
|
} else {
|
||||||
openIndexes = openIndexes.filter((openIndex) => openIndex !== index)
|
openIndexes = openIndexes.filter((openIndex) => openIndex !== index)
|
||||||
$emit("close", { index: index, item: item })
|
output.close({ index: index, item: item })
|
||||||
}
|
}
|
||||||
$emit("toggle", {
|
output.toggle({
|
||||||
index: index,
|
index: index,
|
||||||
item: item,
|
item: item,
|
||||||
open: opening,
|
open: opening,
|
||||||
|
|||||||
@@ -1,32 +1,35 @@
|
|||||||
component ColorPicker {
|
component ColorPicker {
|
||||||
|
outputs {
|
||||||
|
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
focus(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
blur(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event focus = function
|
id: string = ""
|
||||||
@event blur = function
|
name: string = ""
|
||||||
size = "default"
|
label: string = "Color"
|
||||||
color = "primary"
|
hiddenLabel: boolean = false
|
||||||
id = ""
|
placeholder: string = ""
|
||||||
name = ""
|
value: string = "#2563eb"
|
||||||
label = "Color"
|
icon: string = ""
|
||||||
hiddenLabel = false
|
iconPosition: string = "start"
|
||||||
placeholder = ""
|
helperText: string = ""
|
||||||
value = "#2563eb"
|
cornerHint: string = ""
|
||||||
icon = ""
|
error: string = ""
|
||||||
iconPosition = "start"
|
inline: boolean = false
|
||||||
helperText = ""
|
variant: string = "normal"
|
||||||
cornerHint = ""
|
readonly: boolean = false
|
||||||
error = ""
|
disabled: boolean = false
|
||||||
inline = false
|
required: boolean = false
|
||||||
variant = "normal"
|
class: string = ""
|
||||||
readonly = false
|
|
||||||
disabled = false
|
|
||||||
required = false
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
functions {
|
functions {
|
||||||
function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
|
client function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); output[nameEvent]({ value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
|
||||||
function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
|
client function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--color-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--color-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
component Columns {
|
component Columns {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
columns = 2
|
columns: number = 2
|
||||||
gap = "md"
|
gap: string = "md"
|
||||||
maxWidth = "xl"
|
maxWidth: string = "xl"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,71 +1,74 @@
|
|||||||
component ComboBox {
|
component ComboBox {
|
||||||
|
outputs {
|
||||||
|
search(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
clear(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
open(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
close(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
load(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
label = "ComboBox"
|
label: string = "ComboBox"
|
||||||
name = ""
|
name: string = ""
|
||||||
value = ""
|
value: string = ""
|
||||||
options = []
|
options: unknown[] = []
|
||||||
groups = []
|
groups: unknown[] = []
|
||||||
placeholder = "Search or select an option"
|
placeholder: string = "Search or select an option"
|
||||||
searchPlaceholder = "Start typing…"
|
searchPlaceholder: string = "Start typing…"
|
||||||
clearable = true
|
clearable: boolean = true
|
||||||
allowCustomValue = false
|
allowCustomValue: boolean = false
|
||||||
disabled = false
|
disabled: boolean = false
|
||||||
required = false
|
required: boolean = false
|
||||||
invalid = false
|
invalid: boolean = false
|
||||||
validationMessage = ""
|
validationMessage: string = ""
|
||||||
helpText = ""
|
helpText: string = ""
|
||||||
loading = false
|
loading: boolean = false
|
||||||
loadingLabel = "Loading suggestions…"
|
loadingLabel: string = "Loading suggestions…"
|
||||||
emptyLabel = "No matching options"
|
emptyLabel: string = "No matching options"
|
||||||
clearLabel = "Clear value"
|
clearLabel: string = "Clear value"
|
||||||
toggleLabel = "Toggle suggestions"
|
toggleLabel: string = "Toggle suggestions"
|
||||||
searchMode = "contains"
|
searchMode: string = "contains"
|
||||||
searchFields = "label,description"
|
searchFields: string = "label,description"
|
||||||
minSearchLength = 0
|
minSearchLength: number = 0
|
||||||
searchResultLimit = 0
|
searchResultLimit: number = 0
|
||||||
optionTemplate = "default"
|
optionTemplate: string = "default"
|
||||||
defaultOpen = false
|
defaultOpen: boolean = false
|
||||||
closeOnSelect = true
|
closeOnSelect: boolean = true
|
||||||
fixed = false
|
fixed: boolean = false
|
||||||
placement = "bottom"
|
placement: string = "bottom"
|
||||||
autocomplete = "off"
|
autocomplete: string = "off"
|
||||||
remote = false
|
remote: boolean = false
|
||||||
remoteUrl = ""
|
remoteUrl: string = ""
|
||||||
remoteQueryParam = "q"
|
remoteQueryParam: string = "q"
|
||||||
remoteDebounce = 250
|
remoteDebounce: number = 250
|
||||||
remoteAutoLoad = true
|
remoteAutoLoad: boolean = true
|
||||||
infinite = false
|
infinite: boolean = false
|
||||||
hasMore = false
|
hasMore: boolean = false
|
||||||
page = 1
|
page: number = 1
|
||||||
loadMoreLabel = "Load more"
|
loadMoreLabel: string = "Load more"
|
||||||
class = ""
|
class: string = ""
|
||||||
@event search = function
|
|
||||||
@event select = function
|
|
||||||
@event change = function
|
|
||||||
@event clear = function
|
|
||||||
@event open = function
|
|
||||||
@event close = function
|
|
||||||
@event load = function
|
|
||||||
@event error = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state open = defaultOpen
|
state open = defaultOpen
|
||||||
state query = ""
|
state query: string = ""
|
||||||
state selectedValue = value
|
state selectedValue = value
|
||||||
state activeIndex = -1
|
state activeIndex: number = -1
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function allOptions() {
|
shared function allOptions() {
|
||||||
return [...groups.flatMap((group) => group.options || []), ...options]
|
return [...groups.flatMap((group) => group.options || []), ...options]
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchableText(option) {
|
shared function searchableText(option) {
|
||||||
return ((option.label || "") + " " + (option.description || "")).toLowerCase()
|
return ((option.label || "") + " " + (option.description || "")).toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
function matches(option) {
|
shared function matches(option) {
|
||||||
if (!query || query.length < minSearchLength) {
|
if (!query || query.length < minSearchLength) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -78,38 +81,38 @@ component ComboBox {
|
|||||||
return searchableText(option).includes(query.toLowerCase())
|
return searchableText(option).includes(query.toLowerCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
function matchingOptions(list) {
|
shared function matchingOptions(list) {
|
||||||
return list.filter((option) => matches(option))
|
return list.filter((option) => matches(option))
|
||||||
}
|
}
|
||||||
|
|
||||||
function visibleOptions(list) {
|
shared function visibleOptions(list) {
|
||||||
if (searchResultLimit > 0) {
|
if (searchResultLimit > 0) {
|
||||||
return matchingOptions(list).slice(0, searchResultLimit)
|
return matchingOptions(list).slice(0, searchResultLimit)
|
||||||
}
|
}
|
||||||
return matchingOptions(list)
|
return matchingOptions(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
function flatVisibleOptions() {
|
shared function flatVisibleOptions() {
|
||||||
return visibleOptions(allOptions())
|
return visibleOptions(allOptions())
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSelected(option) {
|
shared function isSelected(option) {
|
||||||
return selectedValue === option.value
|
return selectedValue === option.value
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectedOptions() {
|
shared function selectedOptions() {
|
||||||
return allOptions().filter((option) => isSelected(option))
|
return allOptions().filter((option) => isSelected(option))
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectedText() {
|
shared function selectedText() {
|
||||||
return selectedOptions().length ? selectedOptions()[0].label : selectedValue
|
return selectedOptions().length ? selectedOptions()[0].label : selectedValue
|
||||||
}
|
}
|
||||||
|
|
||||||
function inputText() {
|
shared function inputText() {
|
||||||
return query || selectedText()
|
return query || selectedText()
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldShowDropdown() {
|
shared function shouldShowDropdown() {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -125,11 +128,11 @@ component ComboBox {
|
|||||||
return infinite && hasMore
|
return infinite && hasMore
|
||||||
}
|
}
|
||||||
|
|
||||||
function canSelect(option) {
|
shared function canSelect(option) {
|
||||||
return !option.disabled
|
return !option.disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseOption(option) {
|
shared function chooseOption(option) {
|
||||||
if (!canSelect(option)) {
|
if (!canSelect(option)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -141,14 +144,14 @@ component ComboBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateQuery(event) {
|
client function updateQuery(event) {
|
||||||
query = event.target.value
|
query = event.target.value
|
||||||
selectedValue = allowCustomValue ? event.target.value : ""
|
selectedValue = allowCustomValue ? event.target.value : ""
|
||||||
open = true
|
open = true
|
||||||
activeIndex = flatVisibleOptions().length ? 0 : -1
|
activeIndex = flatVisibleOptions().length ? 0 : -1
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearValue(event) {
|
client function clearValue(event) {
|
||||||
if (event) {
|
if (event) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
}
|
}
|
||||||
@@ -158,18 +161,18 @@ component ComboBox {
|
|||||||
open = false
|
open = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function openDropdown() {
|
shared function openDropdown() {
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
open = true
|
open = true
|
||||||
activeIndex = flatVisibleOptions().length ? 0 : -1
|
activeIndex = flatVisibleOptions().length ? 0 : -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeDropdown() {
|
shared function closeDropdown() {
|
||||||
open = false
|
open = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
shared function toggle() {
|
||||||
if (open) {
|
if (open) {
|
||||||
closeDropdown()
|
closeDropdown()
|
||||||
} else {
|
} else {
|
||||||
@@ -177,19 +180,19 @@ component ComboBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setValue(nextValue) {
|
shared function setValue(nextValue) {
|
||||||
selectedValue = nextValue
|
selectedValue = nextValue
|
||||||
query = ""
|
query = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveActive(direction) {
|
shared function moveActive(direction) {
|
||||||
if (!flatVisibleOptions().length) {
|
if (!flatVisibleOptions().length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
activeIndex = (activeIndex + direction + flatVisibleOptions().length) % flatVisibleOptions().length
|
activeIndex = (activeIndex + direction + flatVisibleOptions().length) % flatVisibleOptions().length
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeydown(event) {
|
client function handleKeydown(event) {
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -215,7 +218,7 @@ component ComboBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function optionIndex(option) {
|
shared function optionIndex(option) {
|
||||||
return flatVisibleOptions().findIndex((item) => item.value === option.value)
|
return flatVisibleOptions().findIndex((item) => item.value === option.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
component Confetti {
|
component Confetti {
|
||||||
|
outputs {
|
||||||
|
start(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
complete(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event start = function
|
size: string = "default"
|
||||||
@event complete = function
|
color: string = "primary"
|
||||||
size = "default"
|
title: string = "Confetti"
|
||||||
color = "primary"
|
description: string = ""
|
||||||
title = "Confetti"
|
items: unknown[] = []
|
||||||
description = ""
|
variant: string = "default"
|
||||||
items = []
|
class: string = ""
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--confetti wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--confetti wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,22 +1,521 @@
|
|||||||
component ContextMenu {
|
component ContextMenu {
|
||||||
props {
|
outputs {
|
||||||
@event open = function
|
open(payload: { x: number; y: number; trigger: string; sourceEvent: Event })
|
||||||
@event close = function
|
close(payload: { reason: string; sourceEvent: Event })
|
||||||
@event select = function
|
select(payload: { item: string | number | boolean | null | object; itemIndex: number; value: string | number | boolean; sourceEvent: Event })
|
||||||
size = "default"
|
action(payload: { item: string | number | boolean | null | object; itemIndex: number; value: string | number | boolean; sourceEvent: Event })
|
||||||
color = "primary"
|
|
||||||
title = "Context Menu"
|
|
||||||
description = ""
|
|
||||||
open = false
|
|
||||||
placement = "bottom"
|
|
||||||
closeLabel = "Close"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
|
||||||
|
items: unknown[] = []
|
||||||
|
open: boolean = false
|
||||||
|
defaultOpen: boolean = false
|
||||||
|
trigger: string = "contextmenu"
|
||||||
|
placement: string = "pointer"
|
||||||
|
align: string = "start"
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "raised"
|
||||||
|
title: string = ""
|
||||||
|
description: string = ""
|
||||||
|
label: string = "Context menu"
|
||||||
|
closeOnSelect: boolean = true
|
||||||
|
closeOnOutside: boolean = true
|
||||||
|
disabled: boolean = false
|
||||||
|
minWidth: string = "14rem"
|
||||||
|
maxWidth: string = "20rem"
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
state visible = defaultOpen
|
||||||
|
state positionX: number = 16
|
||||||
|
state positionY: number = 16
|
||||||
|
|
||||||
|
functions {
|
||||||
|
shared function isOpen() {
|
||||||
|
return open || visible
|
||||||
|
}
|
||||||
|
|
||||||
|
client function showMenu(sourceEvent) {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (sourceEvent && sourceEvent.type === "contextmenu") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
}
|
||||||
|
if (placement === "pointer" && sourceEvent) {
|
||||||
|
positionX = Math.max(12, Math.min(sourceEvent.clientX || 12, window.innerWidth - 340))
|
||||||
|
positionY = Math.max(12, Math.min(sourceEvent.clientY || 12, window.innerHeight - 420))
|
||||||
|
}
|
||||||
|
visible = true
|
||||||
|
output.open({
|
||||||
|
x: positionX,
|
||||||
|
y: positionY,
|
||||||
|
trigger: trigger,
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
client function hideMenu(reason, sourceEvent) {
|
||||||
|
visible = false
|
||||||
|
output.close({
|
||||||
|
reason: reason,
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
client function toggleMenu(sourceEvent) {
|
||||||
|
if (isOpen()) {
|
||||||
|
hideMenu("toggle", sourceEvent)
|
||||||
|
} else {
|
||||||
|
showMenu(sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client function chooseItem(item, itemIndex, sourceEvent) {
|
||||||
|
if (disabled || item.disabled || item.type === "header" || item.type === "divider") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
output.select({
|
||||||
|
item: item,
|
||||||
|
itemIndex: itemIndex,
|
||||||
|
value: item.value || "",
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
if (item.action) {
|
||||||
|
output.action({
|
||||||
|
item: item,
|
||||||
|
itemIndex: itemIndex,
|
||||||
|
value: item.value || "",
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (closeOnSelect) {
|
||||||
|
hideMenu("select", sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client function moveFocus(sourceEvent, direction) {
|
||||||
|
const root = sourceEvent.currentTarget.closest(".wire-context-menu") || sourceEvent.currentTarget
|
||||||
|
const options = [...root.querySelectorAll("[data-context-menu-item]:not([disabled])")]
|
||||||
|
if (!options.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const activeIndex = options.indexOf(document.activeElement)
|
||||||
|
const nextIndex = (activeIndex + direction + options.length) % options.length
|
||||||
|
options[nextIndex].focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
client function handleKeydown(sourceEvent) {
|
||||||
|
if (sourceEvent.key === "Escape") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
hideMenu("escape", sourceEvent)
|
||||||
|
} else if (sourceEvent.key === "ArrowDown") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
moveFocus(sourceEvent, 1)
|
||||||
|
} else if (sourceEvent.key === "ArrowUp") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
moveFocus(sourceEvent, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
<div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--context-menu wire-next--placement-{placement} {class}" role="region" aria-modal="false" aria-label="{title}">
|
<div
|
||||||
<header><strong>{title}</strong><button type="button" aria-label="{closeLabel}">×</button></header>
|
{...attrs}
|
||||||
{#if description}<p>{description}</p>{/if}
|
data-ui-component="ContextMenu"
|
||||||
<slot />
|
data-open='{open || visible ? "true" : "false"}'
|
||||||
|
data-trigger='{trigger}'
|
||||||
|
data-placement='{placement}'
|
||||||
|
data-align='{align}'
|
||||||
|
data-size='{size}'
|
||||||
|
data-color='{color}'
|
||||||
|
data-variant='{variant}'
|
||||||
|
class='wire-context-menu {class}'
|
||||||
|
style='--wire-context-x:{positionX}px;--wire-context-y:{positionY}px;--wire-context-min-width:{minWidth};--wire-context-max-width:{maxWidth};'
|
||||||
|
@keydown='handleKeydown(event)'
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="wire-context-menu__trigger"
|
||||||
|
tabindex='{disabled ? "-1" : "0"}'
|
||||||
|
aria-haspopup="menu"
|
||||||
|
aria-expanded='{open || visible ? "true" : "false"}'
|
||||||
|
@contextmenu='if (trigger === "contextmenu" || trigger === "both") { showMenu(event) }'
|
||||||
|
@click='if (trigger === "click" || trigger === "both") { toggleMenu(event) }'
|
||||||
|
@keydown='if (event.key === "Enter" || event.key === " ") { event.preventDefault(); toggleMenu(event) }'
|
||||||
|
>
|
||||||
|
<slot name="trigger"></slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if closeOnOutside}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-context-menu__dismiss-layer"
|
||||||
|
data-show='{open || visible}'
|
||||||
|
aria-label="Close context menu"
|
||||||
|
@click='hideMenu("outside", event)'
|
||||||
|
></button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="wire-context-menu__panel"
|
||||||
|
data-show='{open || visible}'
|
||||||
|
role="menu"
|
||||||
|
aria-label='{label}'
|
||||||
|
>
|
||||||
|
{#if title || description}
|
||||||
|
<div class="wire-context-menu__header">
|
||||||
|
{#if title}
|
||||||
|
<strong>{title}</strong>
|
||||||
|
{/if}
|
||||||
|
{#if description}
|
||||||
|
<span>{description}</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<slot name="header"></slot>
|
||||||
|
|
||||||
|
<div class="wire-context-menu__items">
|
||||||
|
{#each items as item, itemIndex}
|
||||||
|
{#if item.type === "divider"}
|
||||||
|
<div class="wire-context-menu__divider" role="separator"></div>
|
||||||
|
{:else if item.type === "header"}
|
||||||
|
<div class="wire-context-menu__section-label">{item.label || item.title}</div>
|
||||||
|
{:else if item.href}
|
||||||
|
<a
|
||||||
|
href='{item.href}'
|
||||||
|
target='{item.target || ""}'
|
||||||
|
rel='{item.external || item.target === "_blank" ? "noopener noreferrer" : (item.rel || "")}'
|
||||||
|
role="menuitem"
|
||||||
|
data-context-menu-item
|
||||||
|
data-danger='{item.danger ? "true" : "false"}'
|
||||||
|
data-selected='{item.selected || item.checked ? "true" : "false"}'
|
||||||
|
aria-disabled='{item.disabled ? "true" : "false"}'
|
||||||
|
class="wire-context-menu__item"
|
||||||
|
@click='chooseItem(item, itemIndex, event)'
|
||||||
|
>
|
||||||
|
{#if item.icon}
|
||||||
|
<span class='wire-context-menu__icon {item.icon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
<span class="wire-context-menu__copy">
|
||||||
|
<strong>{item.label || item.title}</strong>
|
||||||
|
{#if item.description}
|
||||||
|
<small>{item.description}</small>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{#if item.shortcut}
|
||||||
|
<kbd>{item.shortcut}</kbd>
|
||||||
|
{:else if item.checked || item.selected}
|
||||||
|
<span class="icon-[lucide--check] wire-context-menu__status" aria-hidden="true"></span>
|
||||||
|
{:else if item.external}
|
||||||
|
<span class="icon-[lucide--arrow-up-right] wire-context-menu__status" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
role="menuitem"
|
||||||
|
data-context-menu-item
|
||||||
|
data-danger='{item.danger ? "true" : "false"}'
|
||||||
|
data-selected='{item.selected || item.checked ? "true" : "false"}'
|
||||||
|
disabled='{item.disabled}'
|
||||||
|
class="wire-context-menu__item"
|
||||||
|
@click='chooseItem(item, itemIndex, event)'
|
||||||
|
>
|
||||||
|
{#if item.icon}
|
||||||
|
<span class='wire-context-menu__icon {item.icon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
<span class="wire-context-menu__copy">
|
||||||
|
<strong>{item.label || item.title}</strong>
|
||||||
|
{#if item.description}
|
||||||
|
<small>{item.description}</small>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{#if item.shortcut}
|
||||||
|
<kbd>{item.shortcut}</kbd>
|
||||||
|
{:else if item.checked || item.selected}
|
||||||
|
<span class="icon-[lucide--check] wire-context-menu__status" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<slot></slot>
|
||||||
|
<slot name="footer"></slot>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style {
|
||||||
|
.wire-context-menu {
|
||||||
|
--context-accent: var(--wire-color-primary);
|
||||||
|
--context-soft: var(--wire-color-primary-soft);
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-color="secondary"] {
|
||||||
|
--context-accent: var(--wire-color-secondary);
|
||||||
|
--context-soft: var(--wire-color-secondary-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-color="info"] {
|
||||||
|
--context-accent: var(--wire-color-info);
|
||||||
|
--context-soft: var(--wire-color-info-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-color="success"] {
|
||||||
|
--context-accent: var(--wire-color-success);
|
||||||
|
--context-soft: var(--wire-color-success-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-color="warning"] {
|
||||||
|
--context-accent: var(--wire-color-warning);
|
||||||
|
--context-soft: var(--wire-color-warning-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-color="danger"] {
|
||||||
|
--context-accent: var(--wire-color-danger);
|
||||||
|
--context-soft: var(--wire-color-danger-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__trigger {
|
||||||
|
display: block;
|
||||||
|
min-width: 0;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__trigger:focus-visible {
|
||||||
|
border-radius: 0.6rem;
|
||||||
|
outline: 2px solid var(--wire-color-focus);
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__dismiss-layer {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1090;
|
||||||
|
appearance: none;
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__panel {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1091;
|
||||||
|
top: calc(100% + 0.5rem);
|
||||||
|
left: 0;
|
||||||
|
width: max-content;
|
||||||
|
min-width: var(--wire-context-min-width);
|
||||||
|
max-width: min(var(--wire-context-max-width), calc(100vw - 1.5rem));
|
||||||
|
padding: 0.45rem;
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background:
|
||||||
|
linear-gradient(145deg, color-mix(in srgb, var(--context-accent) 5%, transparent), transparent 58%),
|
||||||
|
color-mix(in srgb, var(--wire-color-surface-raised) 96%, transparent);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--context-accent) 18%, var(--wire-color-border));
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
|
||||||
|
0 24px 64px color-mix(in srgb, black 24%, transparent);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
|
transform-origin: top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-placement="pointer"] .wire-context-menu__panel {
|
||||||
|
position: fixed;
|
||||||
|
top: var(--wire-context-y);
|
||||||
|
left: var(--wire-context-x);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-placement="bottom-end"] .wire-context-menu__panel {
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
transform-origin: top right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-placement="top-start"] .wire-context-menu__panel {
|
||||||
|
top: auto;
|
||||||
|
bottom: calc(100% + 0.5rem);
|
||||||
|
transform-origin: bottom left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-placement="top-end"] .wire-context-menu__panel {
|
||||||
|
top: auto;
|
||||||
|
right: 0;
|
||||||
|
bottom: calc(100% + 0.5rem);
|
||||||
|
left: auto;
|
||||||
|
transform-origin: bottom right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-variant="soft"] .wire-context-menu__panel {
|
||||||
|
background:
|
||||||
|
linear-gradient(145deg, var(--context-soft), transparent 72%),
|
||||||
|
var(--wire-color-surface-raised);
|
||||||
|
box-shadow: 0 18px 48px color-mix(in srgb, black 16%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-variant="outline"] .wire-context-menu__panel {
|
||||||
|
background: var(--wire-color-surface-raised);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__header {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.2rem;
|
||||||
|
padding: 0.65rem 0.75rem 0.75rem;
|
||||||
|
border-bottom: 1px solid var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__header strong {
|
||||||
|
font-size: 0.86rem;
|
||||||
|
font-weight: 650;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__header span {
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__items {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.15rem;
|
||||||
|
padding-block: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__section-label {
|
||||||
|
padding: 0.55rem 0.75rem 0.3rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.68rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__divider {
|
||||||
|
height: 1px;
|
||||||
|
margin: 0.3rem 0.45rem;
|
||||||
|
background: var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__item {
|
||||||
|
appearance: none;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.7rem;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0.65rem 0.7rem;
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0.72rem;
|
||||||
|
font: inherit;
|
||||||
|
text-align: left;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 150ms ease, color 150ms ease, transform 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__item:hover,
|
||||||
|
.wire-context-menu__item:focus-visible,
|
||||||
|
.wire-context-menu__item[data-selected="true"] {
|
||||||
|
color: var(--context-accent);
|
||||||
|
background: var(--context-soft);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__item:active {
|
||||||
|
transform: scale(0.985);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__item[data-danger="true"] {
|
||||||
|
color: var(--wire-color-danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__item[data-danger="true"]:hover,
|
||||||
|
.wire-context-menu__item[data-danger="true"]:focus-visible {
|
||||||
|
background: var(--wire-color-danger-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__item[disabled],
|
||||||
|
.wire-context-menu__item[aria-disabled="true"] {
|
||||||
|
opacity: 0.48;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__icon,
|
||||||
|
.wire-context-menu__status {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__copy {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.12rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__copy strong {
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu__copy small {
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.7rem;
|
||||||
|
line-height: 1.35;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu kbd {
|
||||||
|
padding: 0.16rem 0.38rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
background: var(--wire-color-surface-soft);
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
border-radius: 0.36rem;
|
||||||
|
font-size: 0.64rem;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-size="sm"] .wire-context-menu__item {
|
||||||
|
padding: 0.52rem 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-context-menu[data-size="lg"] .wire-context-menu__item {
|
||||||
|
padding: 0.78rem 0.82rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
.wire-context-menu[data-placement="pointer"] .wire-context-menu__panel {
|
||||||
|
right: 0.75rem;
|
||||||
|
bottom: 0.75rem;
|
||||||
|
left: 0.75rem;
|
||||||
|
top: auto;
|
||||||
|
width: auto;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.wire-context-menu__item {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
component CopyMarkup {
|
component CopyMarkup {
|
||||||
|
outputs {
|
||||||
|
copy(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
success(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event copy = function
|
size: string = "default"
|
||||||
@event success = function
|
color: string = "primary"
|
||||||
@event error = function
|
label: string = "Copy Markup"
|
||||||
size = "default"
|
name: string = ""
|
||||||
color = "primary"
|
value: string = ""
|
||||||
label = "Copy Markup"
|
placeholder: string = ""
|
||||||
name = ""
|
type: string = "text"
|
||||||
value = ""
|
min: string = ""
|
||||||
placeholder = ""
|
max: string = ""
|
||||||
type = "text"
|
step: string = ""
|
||||||
min = ""
|
disabled: boolean = false
|
||||||
max = ""
|
required: boolean = false
|
||||||
step = ""
|
class: string = ""
|
||||||
disabled = false
|
|
||||||
required = false
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--copy-markup {class}"><span>{label}</span><input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" /></label>
|
<label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--copy-markup {class}"><span>{label}</span><input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" /></label>
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
component CustomScrollbar {
|
component CustomScrollbar {
|
||||||
|
outputs {
|
||||||
|
scroll(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event scroll = function
|
size: string = "default"
|
||||||
size = "default"
|
color: string = "primary"
|
||||||
color = "primary"
|
columns: number = 2
|
||||||
columns = 2
|
gap: string = "md"
|
||||||
gap = "md"
|
maxWidth: string = "xl"
|
||||||
maxWidth = "xl"
|
class: string = ""
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--custom-scrollbar wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}"><slot /></div>
|
<div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--custom-scrollbar wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}"><slot /></div>
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
component DataMap {
|
component DataMap {
|
||||||
|
outputs {
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event select = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
size = "default"
|
title: string = "Data Map"
|
||||||
color = "primary"
|
description: string = ""
|
||||||
title = "Data Map"
|
items: unknown[] = []
|
||||||
description = ""
|
variant: string = "default"
|
||||||
items = []
|
class: string = ""
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--data-map wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--data-map wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
component DataTable {
|
component DataTable {
|
||||||
|
outputs {
|
||||||
|
sort(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
rowClick(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
pageChange(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event sort = function
|
size: string = "default"
|
||||||
@event select = function
|
color: string = "primary"
|
||||||
@event change = function
|
caption: string = "Data Table"
|
||||||
@event rowClick = function
|
columns: unknown[] = []
|
||||||
@event pageChange = function
|
rows: unknown[] = []
|
||||||
size = "default"
|
striped: boolean = true
|
||||||
color = "primary"
|
class: string = ""
|
||||||
caption = "Data Table"
|
|
||||||
columns = []
|
|
||||||
rows = []
|
|
||||||
striped = true
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--table {class}"><table><caption>{caption}</caption><thead><tr>{#each columns as column}<th>{column.label}</th>{/each}</tr></thead><tbody>{#each rows as row}<tr>{#each columns as column}<td>{row[column.key]}</td>{/each}</tr>{/each}</tbody></table><slot /></div>
|
<div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--table {class}"><table><caption>{caption}</caption><thead><tr>{#each columns as column}<th>{column.label}</th>{/each}</tr></thead><tbody>{#each rows as row}<tr>{#each columns as column}<td>{row[column.key]}</td>{/each}</tr>{/each}</tbody></table><slot /></div>
|
||||||
|
|||||||
@@ -1,52 +1,55 @@
|
|||||||
component DatePicker {
|
component DatePicker {
|
||||||
|
outputs {
|
||||||
|
input(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
change(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
open(payload: { value: string; name: string; sourceEvent: Event })
|
||||||
|
close(payload: { value: string; name: string; sourceEvent: Event })
|
||||||
|
focus(payload: { value: string; name: string; sourceEvent: Event })
|
||||||
|
blur(payload: { value: string; name: string; sourceEvent: Event })
|
||||||
|
invalid(payload: { name: string; message: string; sourceEvent: Event })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event open = function
|
label: string = "Date Picker"
|
||||||
@event close = function
|
id: string = ""
|
||||||
@event focus = function
|
name: string = ""
|
||||||
@event blur = function
|
value: string = ""
|
||||||
@event invalid = function
|
placeholder: string = ""
|
||||||
size = "default"
|
type: string = "date"
|
||||||
color = "primary"
|
locale: string = "en-US"
|
||||||
label = "Date Picker"
|
firstDayOfWeek: number = 0
|
||||||
id = ""
|
|
||||||
name = ""
|
|
||||||
value = ""
|
|
||||||
placeholder = ""
|
|
||||||
type = "date"
|
|
||||||
locale = "en-US"
|
|
||||||
firstDayOfWeek = 0
|
|
||||||
months = [{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }]
|
months = [{ label: "Jan", value: "01" }, { label: "Feb", value: "02" }, { label: "Mar", value: "03" }, { label: "Apr", value: "04" }, { label: "May", value: "05" }, { label: "Jun", value: "06" }, { label: "Jul", value: "07" }, { label: "Aug", value: "08" }, { label: "Sep", value: "09" }, { label: "Oct", value: "10" }, { label: "Nov", value: "11" }, { label: "Dec", value: "12" }]
|
||||||
days = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
|
days = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
|
||||||
years = [2024, 2025, 2026, 2027, 2028, 2029, 2030]
|
years = [2024, 2025, 2026, 2027, 2028, 2029, 2030]
|
||||||
min = ""
|
min: string = ""
|
||||||
max = ""
|
max: string = ""
|
||||||
step = ""
|
step: string = ""
|
||||||
helperText = ""
|
helperText: string = ""
|
||||||
cornerHint = ""
|
cornerHint: string = ""
|
||||||
error = ""
|
error: string = ""
|
||||||
variant = "normal"
|
variant: string = "normal"
|
||||||
inline = false
|
inline: boolean = false
|
||||||
readonly = false
|
readonly: boolean = false
|
||||||
disabled = false
|
disabled: boolean = false
|
||||||
required = false
|
required: boolean = false
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
state currentValue = value
|
state currentValue = value
|
||||||
state selectedYear = value ? value.split("-")[0] : ""
|
state selectedYear = value ? value.split("-")[0] : ""
|
||||||
state selectedMonth = value ? value.split("-")[1] : ""
|
state selectedMonth = value ? value.split("-")[1] : ""
|
||||||
state selectedDay = value ? value.split("-")[2] : ""
|
state selectedDay = value ? value.split("-")[2] : ""
|
||||||
state expanded = false
|
state expanded: boolean = false
|
||||||
functions {
|
functions {
|
||||||
function openCalendar(sourceEvent) { expanded = true; $emit("open", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function openCalendar(sourceEvent) { expanded = true; output.open({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function updateDate(part, nextValue, sourceEvent, nextDate, detail) { if (part === "year") { selectedYear = String(nextValue) } if (part === "month") { selectedMonth = String(nextValue).padStart(2, "0") } if (part === "day") { selectedDay = String(nextValue).padStart(2, "0") } if (!selectedYear || !selectedMonth || !selectedDay) { return } nextDate = selectedYear + "-" + selectedMonth + "-" + selectedDay; if ((min && nextDate < min) || (max && nextDate > max)) { return } currentValue = nextDate; detail = { value: currentValue, year: selectedYear, month: selectedMonth, day: selectedDay, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
|
client function updateDate(part, nextValue, sourceEvent, nextDate, detail) { if (part === "year") { selectedYear = String(nextValue) } if (part === "month") { selectedMonth = String(nextValue).padStart(2, "0") } if (part === "day") { selectedDay = String(nextValue).padStart(2, "0") } if (!selectedYear || !selectedMonth || !selectedDay) { return } nextDate = selectedYear + "-" + selectedMonth + "-" + selectedDay; if ((min && nextDate < min) || (max && nextDate > max)) { return } currentValue = nextDate; detail = { value: currentValue, year: selectedYear, month: selectedMonth, day: selectedDay, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||||
function finishDate(sourceEvent) { if (!currentValue) { return } expanded = false; $emit("close", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function finishDate(sourceEvent) { if (!currentValue) { return } expanded = false; output.close({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function selectDay(sourceEvent, root, input, nextDate, trigger, detail) { root = sourceEvent.currentTarget.closest(".wire-next--date-picker"); input = root.querySelector(".wire-next__picker-value"); nextDate = input.getAttribute("value").slice(0, 5) + root.querySelector("select").getAttribute("value") + "-" + sourceEvent.currentTarget.dataset.value; currentValue = nextDate; input.setAttribute("value", nextDate); trigger = root.querySelector(".wire-next__date-trigger span"); if (trigger) { trigger.replaceChildren(nextDate) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: nextDate, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
|
client function selectDay(sourceEvent, root, input, nextDate, trigger, detail) { root = sourceEvent.currentTarget.closest(".wire-next--date-picker"); input = root.querySelector(".wire-next__picker-value"); nextDate = input.getAttribute("value").slice(0, 5) + root.querySelector("select").getAttribute("value") + "-" + sourceEvent.currentTarget.dataset.value; currentValue = nextDate; input.setAttribute("value", nextDate); trigger = root.querySelector(".wire-next__date-trigger span"); if (trigger) { trigger.replaceChildren(nextDate) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: nextDate, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||||
function clearDate(sourceEvent, detail) { if (disabled || readonly) { return } currentValue = ""; detail = { value: currentValue, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
|
client function clearDate(sourceEvent, detail) { if (disabled || readonly) { return } currentValue = ""; detail = { value: currentValue, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||||
function handleFocus(sourceEvent) { $emit("focus", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function handleFocus(sourceEvent) { output.focus({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function handleBlur(sourceEvent) { $emit("blur", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function handleBlur(sourceEvent) { output.blur({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function handleInvalid(sourceEvent) { $emit("invalid", { name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
|
client function handleInvalid(sourceEvent) { output.invalid({ name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--date-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
|
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--date-picker {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
|
||||||
|
|||||||
@@ -1,26 +1,29 @@
|
|||||||
component DeviceFrame {
|
component DeviceFrame {
|
||||||
|
outputs {
|
||||||
|
change(payload: { device: string; orientation: string; sourceEvent: Event })
|
||||||
|
rotate(payload: { device: string; orientation: string; sourceEvent: Event })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event change = function
|
size: string = "default"
|
||||||
@event rotate = function
|
color: string = "primary"
|
||||||
size = "default"
|
title: string = "Device Frame"
|
||||||
color = "primary"
|
description: string = ""
|
||||||
title = "Device Frame"
|
items: unknown[] = []
|
||||||
description = ""
|
variant: string = "default"
|
||||||
items = []
|
device: string = "phone"
|
||||||
variant = "default"
|
orientation: string = "portrait"
|
||||||
device = "phone"
|
src: string = ""
|
||||||
orientation = "portrait"
|
srcdoc: string = ""
|
||||||
src = ""
|
frameTitle: string = "Device preview"
|
||||||
srcdoc = ""
|
showToolbar: boolean = true
|
||||||
frameTitle = "Device preview"
|
allow: string = ""
|
||||||
showToolbar = true
|
class: string = ""
|
||||||
allow = ""
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
state currentOrientation = orientation
|
state currentOrientation = orientation
|
||||||
functions {
|
functions {
|
||||||
function setDevice(nextDevice, sourceEvent) { $emit("change", { device: nextDevice, orientation: currentOrientation, sourceEvent: sourceEvent }) }
|
client function setDevice(nextDevice, sourceEvent) { output.change({ device: nextDevice, orientation: currentOrientation, sourceEvent: sourceEvent }) }
|
||||||
function rotateFrame(sourceEvent) { currentOrientation = currentOrientation === "portrait" ? "landscape" : "portrait"; $emit("rotate", { device: device, orientation: currentOrientation, sourceEvent: sourceEvent }); $emit("change", { device: device, orientation: currentOrientation, sourceEvent: sourceEvent }) }
|
client function rotateFrame(sourceEvent) { currentOrientation = currentOrientation === "portrait" ? "landscape" : "portrait"; output.rotate({ device: device, orientation: currentOrientation, sourceEvent: sourceEvent }); output.change({ device: device, orientation: currentOrientation, sourceEvent: sourceEvent }) }
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--device-frame wire-next--variant-{variant} {class}" data-device="{device}" data-orientation="{currentOrientation}">
|
<section {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--device-frame wire-next--variant-{variant} {class}" data-device="{device}" data-orientation="{currentOrientation}">
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
component DragAndDrop {
|
component DragAndDrop {
|
||||||
|
outputs {
|
||||||
|
dragStart(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
dragEnd(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
dragEnter(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
dragLeave(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
drop(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event dragStart = function
|
size: string = "default"
|
||||||
@event dragEnd = function
|
color: string = "primary"
|
||||||
@event dragEnter = function
|
title: string = "Drag And Drop"
|
||||||
@event dragLeave = function
|
description: string = ""
|
||||||
@event drop = function
|
items: unknown[] = []
|
||||||
@event change = function
|
variant: string = "default"
|
||||||
size = "default"
|
class: string = ""
|
||||||
color = "primary"
|
|
||||||
title = "Drag And Drop"
|
|
||||||
description = ""
|
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--drag-and-drop wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--drag-and-drop wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,21 +1,453 @@
|
|||||||
component Drawer {
|
component Drawer {
|
||||||
props {
|
outputs {
|
||||||
@event open = function
|
open(payload: { placement: string; sourceEvent: Event })
|
||||||
@event close = function
|
close(payload: { reason: string; placement: string; sourceEvent: Event })
|
||||||
size = "default"
|
cancel(payload: { placement: string; sourceEvent: Event })
|
||||||
color = "primary"
|
|
||||||
title = "Drawer"
|
|
||||||
description = ""
|
|
||||||
open = false
|
|
||||||
placement = "bottom"
|
|
||||||
closeLabel = "Close"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
open: boolean = false
|
||||||
|
defaultOpen: boolean = false
|
||||||
|
placement: string = "right"
|
||||||
|
size: string = "md"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "default"
|
||||||
|
title: string = "Drawer"
|
||||||
|
description: string = ""
|
||||||
|
icon: string = ""
|
||||||
|
label: string = "Drawer"
|
||||||
|
closeLabel: string = "Close drawer"
|
||||||
|
showClose: boolean = true
|
||||||
|
closeOnBackdrop: boolean = true
|
||||||
|
closeOnEscape: boolean = true
|
||||||
|
overlay: boolean = true
|
||||||
|
scrollable: boolean = true
|
||||||
|
triggerLabel: string = ""
|
||||||
|
triggerIcon: string = ""
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
state visible = defaultOpen
|
||||||
|
|
||||||
|
functions {
|
||||||
|
shared function isOpen() {
|
||||||
|
return open || visible
|
||||||
|
}
|
||||||
|
|
||||||
|
client function showDrawer(sourceEvent) {
|
||||||
|
visible = true
|
||||||
|
output.open({
|
||||||
|
placement: placement,
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
client function hideDrawer(reason, sourceEvent) {
|
||||||
|
visible = false
|
||||||
|
output.close({
|
||||||
|
reason: reason,
|
||||||
|
placement: placement,
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
client function cancelDrawer(sourceEvent) {
|
||||||
|
output.cancel({
|
||||||
|
placement: placement,
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
hideDrawer("cancel", sourceEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
client function handleKeydown(sourceEvent) {
|
||||||
|
if (closeOnEscape && sourceEvent.key === "Escape") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
cancelDrawer(sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
<div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--drawer wire-next--placement-{placement} {class}" role="dialog" aria-modal="true" aria-label="{title}">
|
<div
|
||||||
<header><strong>{title}</strong><button type="button" aria-label="{closeLabel}">×</button></header>
|
{...attrs}
|
||||||
{#if description}<p>{description}</p>{/if}
|
data-ui-component="Drawer"
|
||||||
<slot />
|
data-open='{open || visible ? "true" : "false"}'
|
||||||
|
data-placement='{placement}'
|
||||||
|
data-size='{size}'
|
||||||
|
data-color='{color}'
|
||||||
|
data-variant='{variant}'
|
||||||
|
data-overlay='{overlay ? "true" : "false"}'
|
||||||
|
data-scrollable='{scrollable ? "true" : "false"}'
|
||||||
|
class='wire-drawer {class}'
|
||||||
|
>
|
||||||
|
{#if triggerLabel}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-drawer__trigger"
|
||||||
|
aria-haspopup="dialog"
|
||||||
|
aria-expanded='{open || visible ? "true" : "false"}'
|
||||||
|
@click='showDrawer(event)'
|
||||||
|
>
|
||||||
|
{#if triggerIcon}
|
||||||
|
<span class='{triggerIcon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
<span>{triggerLabel}</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<span class="wire-drawer__trigger-slot" @click='showDrawer(event)'>
|
||||||
|
<slot name="trigger"></slot>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="wire-drawer__layer"
|
||||||
|
data-show='{open || visible}'
|
||||||
|
role="presentation"
|
||||||
|
@keydown='handleKeydown(event)'
|
||||||
|
>
|
||||||
|
{#if overlay}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-drawer__backdrop"
|
||||||
|
aria-label='{closeLabel}'
|
||||||
|
@click='if (closeOnBackdrop) { cancelDrawer(event) }'
|
||||||
|
></button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="wire-drawer__panel"
|
||||||
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-label='{label || title}'
|
||||||
|
tabindex="-1"
|
||||||
|
>
|
||||||
|
<div class="wire-drawer__handle" aria-hidden="true"></div>
|
||||||
|
|
||||||
|
<header class="wire-drawer__header">
|
||||||
|
<div class="wire-drawer__heading">
|
||||||
|
{#if icon}
|
||||||
|
<span class='wire-drawer__icon {icon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="wire-drawer__heading-copy">
|
||||||
|
<slot name="header"></slot>
|
||||||
|
{#if title}
|
||||||
|
<h2>{title}</h2>
|
||||||
|
{/if}
|
||||||
|
{#if description}
|
||||||
|
<p>{description}</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if showClose}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-drawer__close"
|
||||||
|
aria-label='{closeLabel}'
|
||||||
|
@click='hideDrawer("close-button", event)'
|
||||||
|
>
|
||||||
|
<span class="icon-[lucide--x]" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="wire-drawer__body">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="wire-drawer__footer">
|
||||||
|
<slot name="footer"></slot>
|
||||||
|
</footer>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style {
|
||||||
|
.wire-drawer {
|
||||||
|
--drawer-accent: var(--wire-color-primary);
|
||||||
|
--drawer-soft: var(--wire-color-primary-soft);
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-color="secondary"] {
|
||||||
|
--drawer-accent: var(--wire-color-secondary);
|
||||||
|
--drawer-soft: var(--wire-color-secondary-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-color="info"] {
|
||||||
|
--drawer-accent: var(--wire-color-info);
|
||||||
|
--drawer-soft: var(--wire-color-info-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-color="success"] {
|
||||||
|
--drawer-accent: var(--wire-color-success);
|
||||||
|
--drawer-soft: var(--wire-color-success-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-color="warning"] {
|
||||||
|
--drawer-accent: var(--wire-color-warning);
|
||||||
|
--drawer-soft: var(--wire-color-warning-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-color="danger"] {
|
||||||
|
--drawer-accent: var(--wire-color-danger);
|
||||||
|
--drawer-soft: var(--wire-color-danger-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__trigger,
|
||||||
|
.wire-drawer__trigger-slot {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.55rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__trigger {
|
||||||
|
appearance: none;
|
||||||
|
min-height: 2.55rem;
|
||||||
|
padding: 0.65rem 1rem;
|
||||||
|
color: var(--wire-color-primary-contrast);
|
||||||
|
background: var(--drawer-accent);
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0.8rem;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 650;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__layer {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1200;
|
||||||
|
display: flex;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__backdrop {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
appearance: none;
|
||||||
|
padding: 0;
|
||||||
|
background: color-mix(in srgb, black 56%, transparent);
|
||||||
|
border: 0;
|
||||||
|
backdrop-filter: blur(7px);
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-overlay="false"] .wire-drawer__backdrop {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__panel {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: min(28rem, calc(100vw - 1rem));
|
||||||
|
max-height: 100%;
|
||||||
|
margin-left: auto;
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background:
|
||||||
|
radial-gradient(
|
||||||
|
circle at 100% 0%,
|
||||||
|
color-mix(in srgb, var(--drawer-accent) 8%, transparent),
|
||||||
|
transparent 34%
|
||||||
|
),
|
||||||
|
var(--wire-color-surface-raised);
|
||||||
|
border-left: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wire-color-border));
|
||||||
|
box-shadow: -28px 0 80px color-mix(in srgb, black 28%, transparent);
|
||||||
|
pointer-events: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-size="sm"] .wire-drawer__panel {
|
||||||
|
width: min(22rem, calc(100vw - 1rem));
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-size="lg"] .wire-drawer__panel {
|
||||||
|
width: min(38rem, calc(100vw - 1rem));
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-size="xl"] .wire-drawer__panel {
|
||||||
|
width: min(52rem, calc(100vw - 1rem));
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-size="full"] .wire-drawer__panel {
|
||||||
|
width: 100vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-placement="left"] .wire-drawer__panel {
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: 0;
|
||||||
|
border-right: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wire-color-border));
|
||||||
|
border-left: 0;
|
||||||
|
box-shadow: 28px 0 80px color-mix(in srgb, black 28%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-placement="top"] .wire-drawer__layer,
|
||||||
|
.wire-drawer[data-placement="bottom"] .wire-drawer__layer {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-placement="top"] .wire-drawer__panel,
|
||||||
|
.wire-drawer[data-placement="bottom"] .wire-drawer__panel {
|
||||||
|
width: 100%;
|
||||||
|
max-height: min(80vh, 44rem);
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
box-shadow: 0 24px 80px color-mix(in srgb, black 28%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-placement="top"] .wire-drawer__panel {
|
||||||
|
border-bottom: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wire-color-border));
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-placement="bottom"] .wire-drawer__layer {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-placement="bottom"] .wire-drawer__panel {
|
||||||
|
border-top: 1px solid color-mix(in srgb, var(--drawer-accent) 18%, var(--wire-color-border));
|
||||||
|
border-radius: 1.3rem 1.3rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-variant="soft"] .wire-drawer__panel {
|
||||||
|
background:
|
||||||
|
linear-gradient(145deg, var(--drawer-soft), transparent 65%),
|
||||||
|
var(--wire-color-surface-raised);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-variant="solid"] .wire-drawer__panel {
|
||||||
|
color: var(--wire-color-primary-contrast);
|
||||||
|
background: var(--drawer-accent);
|
||||||
|
border-color: color-mix(in srgb, white 18%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__handle {
|
||||||
|
display: none;
|
||||||
|
width: 2.75rem;
|
||||||
|
height: 0.28rem;
|
||||||
|
margin: 0.55rem auto 0;
|
||||||
|
background: color-mix(in srgb, var(--wire-color-text-muted) 48%, transparent);
|
||||||
|
border-radius: 999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-placement="bottom"] .wire-drawer__handle {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1.35rem 1.35rem 1.1rem;
|
||||||
|
border-bottom: 1px solid var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__heading {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.85rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__icon {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
margin-top: 0.15rem;
|
||||||
|
color: var(--drawer-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-variant="solid"] .wire-drawer__icon {
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__heading-copy {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.3rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__heading-copy h2,
|
||||||
|
.wire-drawer__heading-copy p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__heading-copy h2 {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__heading-copy p {
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-variant="solid"] .wire-drawer__heading-copy p {
|
||||||
|
color: color-mix(in srgb, currentColor 76%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__close {
|
||||||
|
appearance: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 2.35rem;
|
||||||
|
height: 2.35rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
background: var(--wire-color-surface-soft);
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__close:hover,
|
||||||
|
.wire-drawer__close:focus-visible {
|
||||||
|
color: var(--drawer-accent);
|
||||||
|
border-color: color-mix(in srgb, var(--drawer-accent) 34%, var(--wire-color-border));
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__body {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
padding: 1.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer[data-scrollable="true"] .wire-drawer__body {
|
||||||
|
overflow: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__footer {
|
||||||
|
padding: 1rem 1.35rem 1.35rem;
|
||||||
|
border-top: 1px solid var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__footer:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
.wire-drawer[data-placement="right"] .wire-drawer__panel,
|
||||||
|
.wire-drawer[data-placement="left"] .wire-drawer__panel {
|
||||||
|
width: min(24rem, 100vw);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-drawer__header,
|
||||||
|
.wire-drawer__body,
|
||||||
|
.wire-drawer__footer {
|
||||||
|
padding-inline: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,572 @@
|
|||||||
component Dropdown {
|
component Dropdown {
|
||||||
props {
|
outputs {
|
||||||
@event toggle = function
|
toggle(payload: { open: boolean; sourceEvent: Event; reason?: object })
|
||||||
@event open = function
|
open(payload: { sourceEvent: Event })
|
||||||
@event close = function
|
close(payload: { reason: string; sourceEvent: Event })
|
||||||
@event select = function
|
select(payload: { item: string | number | boolean | null | object; itemIndex: number; value: string | number | boolean; sourceEvent: Event })
|
||||||
size = "default"
|
action(payload: { item: string | number | boolean | null | object; itemIndex: number; value: string | number | boolean; sourceEvent: Event })
|
||||||
color = "primary"
|
|
||||||
label = "Open menu"
|
|
||||||
items = []
|
|
||||||
placement = "end"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
items: unknown[] = []
|
||||||
|
open: boolean = false
|
||||||
|
defaultOpen: boolean = false
|
||||||
|
label: string = "Open menu"
|
||||||
|
icon: string = ""
|
||||||
|
showChevron: boolean = true
|
||||||
|
menuLabel: string = "Dropdown menu"
|
||||||
|
placement: string = "bottom-start"
|
||||||
|
width: string = "md"
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "raised"
|
||||||
|
closeOnSelect: boolean = true
|
||||||
|
closeOnOutside: boolean = true
|
||||||
|
disabled: boolean = false
|
||||||
|
emptyLabel: string = "No menu items"
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
state visible = defaultOpen
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function toggleMenu(event) {
|
shared function isOpen() {
|
||||||
$emit("toggle", { open: event.currentTarget.open })
|
return open || visible
|
||||||
$emit(event.currentTarget.open ? "open" : "close", { source: "trigger" })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectItem(item) {
|
client function showMenu(sourceEvent) {
|
||||||
$emit("select", { item: item, value: item.value || "" })
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
visible = true
|
||||||
|
output.open({ sourceEvent: sourceEvent })
|
||||||
|
output.toggle({ open: true, sourceEvent: sourceEvent })
|
||||||
|
}
|
||||||
|
|
||||||
|
client function hideMenu(reason, sourceEvent) {
|
||||||
|
visible = false
|
||||||
|
output.close({ reason: reason, sourceEvent: sourceEvent })
|
||||||
|
output.toggle({ open: false, reason: reason, sourceEvent: sourceEvent })
|
||||||
|
}
|
||||||
|
|
||||||
|
client function toggleMenu(sourceEvent) {
|
||||||
|
if (isOpen()) {
|
||||||
|
hideMenu("toggle", sourceEvent)
|
||||||
|
} else {
|
||||||
|
showMenu(sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client function chooseItem(item, itemIndex, sourceEvent) {
|
||||||
|
if (disabled || item.disabled || item.type === "divider" || item.type === "header") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
output.select({
|
||||||
|
item: item,
|
||||||
|
itemIndex: itemIndex,
|
||||||
|
value: item.value || "",
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
if (item.action) {
|
||||||
|
output.action({
|
||||||
|
item: item,
|
||||||
|
itemIndex: itemIndex,
|
||||||
|
value: item.value || "",
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (closeOnSelect) {
|
||||||
|
hideMenu("select", sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client function moveFocus(sourceEvent, direction) {
|
||||||
|
const root = sourceEvent.currentTarget.closest(".wire-dropdown") || sourceEvent.currentTarget
|
||||||
|
const options = [...root.querySelectorAll("[data-dropdown-item]:not([disabled])")]
|
||||||
|
if (!options.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const activeIndex = options.indexOf(document.activeElement)
|
||||||
|
const nextIndex = (activeIndex + direction + options.length) % options.length
|
||||||
|
options[nextIndex].focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
client function handleKeydown(sourceEvent) {
|
||||||
|
if (sourceEvent.key === "Escape") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
hideMenu("escape", sourceEvent)
|
||||||
|
} else if (sourceEvent.key === "ArrowDown") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
if (!isOpen()) {
|
||||||
|
showMenu(sourceEvent)
|
||||||
|
}
|
||||||
|
moveFocus(sourceEvent, 1)
|
||||||
|
} else if (sourceEvent.key === "ArrowUp") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
if (!isOpen()) {
|
||||||
|
showMenu(sourceEvent)
|
||||||
|
}
|
||||||
|
moveFocus(sourceEvent, -1)
|
||||||
|
} else if (sourceEvent.key === "Home" && isOpen()) {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
const root = sourceEvent.currentTarget.closest(".wire-dropdown") || sourceEvent.currentTarget
|
||||||
|
const first = root.querySelector("[data-dropdown-item]:not([disabled])")
|
||||||
|
if (first) {
|
||||||
|
first.focus()
|
||||||
|
}
|
||||||
|
} else if (sourceEvent.key === "End" && isOpen()) {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
const root = sourceEvent.currentTarget.closest(".wire-dropdown") || sourceEvent.currentTarget
|
||||||
|
const options = [...root.querySelectorAll("[data-dropdown-item]:not([disabled])")]
|
||||||
|
if (options.length) {
|
||||||
|
options[options.length - 1].focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
<details class="wire-dropdown wire-dropdown--{placement} wire-next--color-{color} wire-next--size-{size} {class}" data-wrn-dropdown @toggle="toggleMenu($event)">
|
<div
|
||||||
<summary aria-label="{label}">
|
{...attrs}
|
||||||
<slot name="trigger" />
|
data-ui-component="Dropdown"
|
||||||
<span class="wire-dropdown__chevron icon-[lucide--chevron-down]" aria-hidden="true"></span>
|
data-open='{open || visible ? "true" : "false"}'
|
||||||
</summary>
|
data-placement='{placement}'
|
||||||
<div class="wire-dropdown__panel" role="menu" aria-label="{label}">
|
data-width='{width}'
|
||||||
<slot name="header" />
|
data-size='{size}'
|
||||||
{#each items as item}
|
data-color='{color}'
|
||||||
{#if item.type === "divider"}
|
data-variant='{variant}'
|
||||||
<hr />
|
class='wire-dropdown {class}'
|
||||||
{:else}
|
@keydown='handleKeydown(event)'
|
||||||
{#if item.type === "header"}
|
>
|
||||||
<span class="wire-dropdown__heading">{item.label}</span>
|
<button
|
||||||
{:else}
|
type="button"
|
||||||
<a class="wire-dropdown__item {item.danger ? 'wire-dropdown__item--danger' : ''}" href="{item.href || '#'}" target="{item.target || ''}" rel="{item.rel || ''}" role="menuitem" @click="selectItem(item)">
|
class="wire-dropdown__trigger"
|
||||||
{#if item.icon}<span class="{item.icon}" aria-hidden="true"></span>{/if}
|
disabled='{disabled}'
|
||||||
<span><strong>{item.label}</strong>{#if item.description}<small>{item.description}</small>{/if}</span>
|
aria-haspopup="menu"
|
||||||
{#if item.external}<span class="icon-[lucide--arrow-up-right]" aria-hidden="true"></span>{/if}
|
aria-expanded='{open || visible ? "true" : "false"}'
|
||||||
|
@click='toggleMenu(event)'
|
||||||
|
>
|
||||||
|
<slot name="trigger"></slot>
|
||||||
|
{#if icon}
|
||||||
|
<span class='wire-dropdown__trigger-icon {icon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
{#if label}
|
||||||
|
<span class="wire-dropdown__trigger-label">{label}</span>
|
||||||
|
{/if}
|
||||||
|
{#if showChevron}
|
||||||
|
<span class="icon-[lucide--chevron-down] wire-dropdown__chevron" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{#if closeOnOutside}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-dropdown__dismiss-layer"
|
||||||
|
data-show='{open || visible}'
|
||||||
|
aria-label="Close menu"
|
||||||
|
@click='hideMenu("outside", event)'
|
||||||
|
></button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="wire-dropdown__panel"
|
||||||
|
data-show='{open || visible}'
|
||||||
|
role="menu"
|
||||||
|
aria-label='{menuLabel}'
|
||||||
|
>
|
||||||
|
<slot name="header"></slot>
|
||||||
|
|
||||||
|
<div class="wire-dropdown__items">
|
||||||
|
{#each items as item, itemIndex}
|
||||||
|
{#if item.type === "divider"}
|
||||||
|
<div class="wire-dropdown__divider" role="separator"></div>
|
||||||
|
{:else if item.type === "header"}
|
||||||
|
<div class="wire-dropdown__section-label">{item.label || item.title}</div>
|
||||||
|
{:else if item.href}
|
||||||
|
<a
|
||||||
|
href='{item.href}'
|
||||||
|
target='{item.target || ""}'
|
||||||
|
rel='{item.external || item.target === "_blank" ? "noopener noreferrer" : (item.rel || "")}'
|
||||||
|
role="menuitem"
|
||||||
|
data-dropdown-item
|
||||||
|
data-danger='{item.danger ? "true" : "false"}'
|
||||||
|
data-selected='{item.selected || item.checked ? "true" : "false"}'
|
||||||
|
aria-disabled='{item.disabled ? "true" : "false"}'
|
||||||
|
class="wire-dropdown__item"
|
||||||
|
@click='chooseItem(item, itemIndex, event)'
|
||||||
|
>
|
||||||
|
{#if item.icon}
|
||||||
|
<span class='wire-dropdown__item-icon {item.icon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
<span class="wire-dropdown__copy">
|
||||||
|
<strong>{item.label || item.title}</strong>
|
||||||
|
{#if item.description}
|
||||||
|
<small>{item.description}</small>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{#if item.badge}
|
||||||
|
<span class="wire-dropdown__badge">{item.badge}</span>
|
||||||
|
{:else if item.shortcut}
|
||||||
|
<kbd>{item.shortcut}</kbd>
|
||||||
|
{:else if item.checked || item.selected}
|
||||||
|
<span class="icon-[lucide--check] wire-dropdown__status" aria-hidden="true"></span>
|
||||||
|
{:else if item.external}
|
||||||
|
<span class="icon-[lucide--arrow-up-right] wire-dropdown__status" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
</a>
|
</a>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
role="menuitem"
|
||||||
|
data-dropdown-item
|
||||||
|
data-danger='{item.danger ? "true" : "false"}'
|
||||||
|
data-selected='{item.selected || item.checked ? "true" : "false"}'
|
||||||
|
disabled='{item.disabled}'
|
||||||
|
class="wire-dropdown__item"
|
||||||
|
@click='chooseItem(item, itemIndex, event)'
|
||||||
|
>
|
||||||
|
{#if item.icon}
|
||||||
|
<span class='wire-dropdown__item-icon {item.icon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
<span class="wire-dropdown__copy">
|
||||||
|
<strong>{item.label || item.title}</strong>
|
||||||
|
{#if item.description}
|
||||||
|
<small>{item.description}</small>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{#if item.badge}
|
||||||
|
<span class="wire-dropdown__badge">{item.badge}</span>
|
||||||
|
{:else if item.shortcut}
|
||||||
|
<kbd>{item.shortcut}</kbd>
|
||||||
|
{:else if item.checked || item.selected}
|
||||||
|
<span class="icon-[lucide--check] wire-dropdown__status" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{:empty}
|
||||||
{/each}
|
<div class="wire-dropdown__empty">{emptyLabel}</div>
|
||||||
<slot name="footer" />
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<slot></slot>
|
||||||
|
<slot name="footer"></slot>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
style {
|
||||||
|
.wire-dropdown {
|
||||||
|
--dropdown-accent: var(--wire-color-primary);
|
||||||
|
--dropdown-soft: var(--wire-color-primary-soft);
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-color="secondary"] {
|
||||||
|
--dropdown-accent: var(--wire-color-secondary);
|
||||||
|
--dropdown-soft: var(--wire-color-secondary-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-color="info"] {
|
||||||
|
--dropdown-accent: var(--wire-color-info);
|
||||||
|
--dropdown-soft: var(--wire-color-info-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-color="success"] {
|
||||||
|
--dropdown-accent: var(--wire-color-success);
|
||||||
|
--dropdown-soft: var(--wire-color-success-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-color="warning"] {
|
||||||
|
--dropdown-accent: var(--wire-color-warning);
|
||||||
|
--dropdown-soft: var(--wire-color-warning-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-color="danger"] {
|
||||||
|
--dropdown-accent: var(--wire-color-danger);
|
||||||
|
--dropdown-soft: var(--wire-color-danger-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__trigger {
|
||||||
|
appearance: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.55rem;
|
||||||
|
min-height: 2.55rem;
|
||||||
|
padding: 0.65rem 0.9rem;
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background: var(--wire-color-surface-raised);
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
border-radius: 0.78rem;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.84rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 150ms ease, background-color 150ms ease, color 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__trigger:hover,
|
||||||
|
.wire-dropdown__trigger:focus-visible,
|
||||||
|
.wire-dropdown[data-open="true"] .wire-dropdown__trigger {
|
||||||
|
color: var(--dropdown-accent);
|
||||||
|
background: var(--dropdown-soft);
|
||||||
|
border-color: color-mix(in srgb, var(--dropdown-accent) 38%, var(--wire-color-border));
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__trigger:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__trigger-icon,
|
||||||
|
.wire-dropdown__chevron {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__chevron {
|
||||||
|
transition: transform 160ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-open="true"] .wire-dropdown__chevron {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-size="sm"] .wire-dropdown__trigger {
|
||||||
|
min-height: 2.2rem;
|
||||||
|
padding: 0.5rem 0.72rem;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-size="lg"] .wire-dropdown__trigger {
|
||||||
|
min-height: 2.9rem;
|
||||||
|
padding: 0.78rem 1.05rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__dismiss-layer {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1100;
|
||||||
|
appearance: none;
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__panel {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1101;
|
||||||
|
top: calc(100% + 0.55rem);
|
||||||
|
left: 0;
|
||||||
|
width: max-content;
|
||||||
|
min-width: 12rem;
|
||||||
|
max-width: min(22rem, calc(100vw - 1.5rem));
|
||||||
|
padding: 0.45rem;
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background:
|
||||||
|
linear-gradient(145deg, color-mix(in srgb, var(--dropdown-accent) 5%, transparent), transparent 60%),
|
||||||
|
color-mix(in srgb, var(--wire-color-surface-raised) 97%, transparent);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--dropdown-accent) 18%, var(--wire-color-border));
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
|
||||||
|
0 24px 64px color-mix(in srgb, black 22%, transparent);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-width="trigger"] .wire-dropdown__panel {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-width="sm"] .wire-dropdown__panel {
|
||||||
|
width: 12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-width="md"] .wire-dropdown__panel {
|
||||||
|
width: 17rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-width="lg"] .wire-dropdown__panel {
|
||||||
|
width: 22rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-placement="bottom-end"] .wire-dropdown__panel {
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-placement="top-start"] .wire-dropdown__panel {
|
||||||
|
top: auto;
|
||||||
|
bottom: calc(100% + 0.55rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-placement="top-end"] .wire-dropdown__panel {
|
||||||
|
top: auto;
|
||||||
|
right: 0;
|
||||||
|
bottom: calc(100% + 0.55rem);
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-variant="soft"] .wire-dropdown__panel {
|
||||||
|
background:
|
||||||
|
linear-gradient(145deg, var(--dropdown-soft), transparent 70%),
|
||||||
|
var(--wire-color-surface-raised);
|
||||||
|
box-shadow: 0 18px 48px color-mix(in srgb, black 16%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown[data-variant="outline"] .wire-dropdown__panel {
|
||||||
|
background: var(--wire-color-surface-raised);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__items {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__section-label {
|
||||||
|
padding: 0.55rem 0.72rem 0.3rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.68rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__divider {
|
||||||
|
height: 1px;
|
||||||
|
margin: 0.3rem 0.4rem;
|
||||||
|
background: var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__item {
|
||||||
|
appearance: none;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.7rem;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0.68rem 0.72rem;
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0.72rem;
|
||||||
|
font: inherit;
|
||||||
|
text-align: left;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 150ms ease, color 150ms ease, transform 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__item:hover,
|
||||||
|
.wire-dropdown__item:focus-visible,
|
||||||
|
.wire-dropdown__item[data-selected="true"] {
|
||||||
|
color: var(--dropdown-accent);
|
||||||
|
background: var(--dropdown-soft);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__item:active {
|
||||||
|
transform: scale(0.985);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__item[data-danger="true"] {
|
||||||
|
color: var(--wire-color-danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__item[data-danger="true"]:hover,
|
||||||
|
.wire-dropdown__item[data-danger="true"]:focus-visible {
|
||||||
|
background: var(--wire-color-danger-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__item[disabled],
|
||||||
|
.wire-dropdown__item[aria-disabled="true"] {
|
||||||
|
opacity: 0.48;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__item-icon,
|
||||||
|
.wire-dropdown__status {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__copy {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.12rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__copy strong {
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__copy small {
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.7rem;
|
||||||
|
line-height: 1.35;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__badge {
|
||||||
|
padding: 0.18rem 0.45rem;
|
||||||
|
color: var(--dropdown-accent);
|
||||||
|
background: var(--dropdown-soft);
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 0.64rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown kbd {
|
||||||
|
padding: 0.16rem 0.38rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
background: var(--wire-color-surface-soft);
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
border-radius: 0.36rem;
|
||||||
|
font-size: 0.64rem;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-dropdown__empty {
|
||||||
|
padding: 1rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
.wire-dropdown__panel {
|
||||||
|
position: fixed;
|
||||||
|
right: 0.75rem;
|
||||||
|
bottom: 0.75rem;
|
||||||
|
left: 0.75rem;
|
||||||
|
top: auto;
|
||||||
|
width: auto;
|
||||||
|
min-width: 0;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.wire-dropdown__trigger,
|
||||||
|
.wire-dropdown__chevron,
|
||||||
|
.wire-dropdown__item {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,49 @@
|
|||||||
component FileInput {
|
component FileInput {
|
||||||
props {
|
outputs {
|
||||||
@event input = function
|
input(payload: { files: File[]; name: string; sourceEvent: Event })
|
||||||
@event change = function
|
change(payload: { files: File[]; name: string; sourceEvent: Event })
|
||||||
@event focus = function
|
focus(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event blur = function
|
blur(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event select = function
|
select(payload: { files: File[]; name: string; sourceEvent: Event })
|
||||||
@event clear = function
|
clear(payload: { name: string; sourceEvent: Event })
|
||||||
@event invalid = function
|
invalid(payload: { message?: string; value: string | number | boolean | null | object; sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
size = "default"
|
|
||||||
color = "primary"
|
|
||||||
id = ""
|
|
||||||
name = ""
|
|
||||||
label = "File"
|
|
||||||
hiddenLabel = false
|
|
||||||
placeholder = "Choose a file"
|
|
||||||
value = ""
|
|
||||||
icon = "icon-[lucide--upload]"
|
|
||||||
iconPosition = "start"
|
|
||||||
accept = ""
|
|
||||||
multiple = false
|
|
||||||
helperText = ""
|
|
||||||
cornerHint = ""
|
|
||||||
error = ""
|
|
||||||
inline = false
|
|
||||||
variant = "normal"
|
|
||||||
readonly = false
|
|
||||||
disabled = false
|
|
||||||
required = false
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
state selectedName = ""
|
|
||||||
|
props {
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
id: string = ""
|
||||||
|
name: string = ""
|
||||||
|
label: string = "File"
|
||||||
|
hiddenLabel: boolean = false
|
||||||
|
placeholder: string = "Choose a file"
|
||||||
|
value: string = ""
|
||||||
|
icon: string = "icon-[lucide--upload]"
|
||||||
|
iconPosition: string = "start"
|
||||||
|
accept: string = ""
|
||||||
|
multiple: boolean = false
|
||||||
|
helperText: string = ""
|
||||||
|
cornerHint: string = ""
|
||||||
|
error: string = ""
|
||||||
|
inline: boolean = false
|
||||||
|
variant: string = "normal"
|
||||||
|
readonly: boolean = false
|
||||||
|
disabled: boolean = false
|
||||||
|
required: boolean = false
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
state selectedName: string = ""
|
||||||
functions {
|
functions {
|
||||||
function handleChange(sourceEvent) {
|
client function handleChange(sourceEvent) {
|
||||||
sourceEvent.stopPropagation()
|
sourceEvent.stopPropagation()
|
||||||
selectedName = sourceEvent.currentTarget.files && sourceEvent.currentTarget.files.length ? sourceEvent.currentTarget.files[0].name : ""
|
selectedName = sourceEvent.currentTarget.files && sourceEvent.currentTarget.files.length ? sourceEvent.currentTarget.files[0].name : ""
|
||||||
$emit("input", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
|
output.input({ files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
|
||||||
$emit("change", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
|
output.change({ files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
|
||||||
if (selectedName) $emit("select", { files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
|
if (selectedName) output.select({ files: sourceEvent.currentTarget.files, name: name, sourceEvent: sourceEvent })
|
||||||
else $emit("clear", { name: name, sourceEvent: sourceEvent })
|
else output.clear({ name: name, sourceEvent: sourceEvent })
|
||||||
}
|
}
|
||||||
function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { name: name, sourceEvent: sourceEvent }) }
|
client function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); output[nameEvent]({ name: name, sourceEvent: sourceEvent }) }
|
||||||
function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
|
client function preventReadonly(sourceEvent) { if (readonly) sourceEvent.preventDefault() }
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--file-input {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--file-input {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
component FileUpload {
|
component FileUpload {
|
||||||
|
outputs {
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
upload(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
progress(payload: { progress: number; [key: string]: string | number | boolean | null | object } | number)
|
||||||
|
success(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string)
|
||||||
|
cancel(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
remove(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event select = function
|
size: string = "default"
|
||||||
@event upload = function
|
color: string = "primary"
|
||||||
@event progress = function
|
title: string = "File Upload"
|
||||||
@event success = function
|
description: string = ""
|
||||||
@event error = function
|
items: unknown[] = []
|
||||||
@event cancel = function
|
variant: string = "default"
|
||||||
@event remove = function
|
class: string = ""
|
||||||
size = "default"
|
|
||||||
color = "primary"
|
|
||||||
title = "File Upload"
|
|
||||||
description = ""
|
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,30 +1,33 @@
|
|||||||
component FileUploadProgress {
|
component FileUploadProgress {
|
||||||
|
outputs {
|
||||||
|
cancel(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
retry(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
complete(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event cancel = function
|
size: string = "default"
|
||||||
@event retry = function
|
color: string = "primary"
|
||||||
@event complete = function
|
label: string = "Progress"
|
||||||
size = "default"
|
value: number = 50
|
||||||
color = "primary"
|
max: number = 100
|
||||||
label = "Progress"
|
showValue: boolean = true
|
||||||
value = 50
|
fileName: string = ""
|
||||||
max = 100
|
fileSize: string = ""
|
||||||
showValue = true
|
uploadedSize: string = ""
|
||||||
fileName = ""
|
status: string = "uploading"
|
||||||
fileSize = ""
|
cancelLabel: string = "Cancel upload"
|
||||||
uploadedSize = ""
|
retryLabel: string = "Retry upload"
|
||||||
status = "uploading"
|
class: string = ""
|
||||||
cancelLabel = "Cancel upload"
|
|
||||||
retryLabel = "Retry upload"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
state currentValue = value
|
state currentValue = value
|
||||||
state currentStatus = status
|
state currentStatus = status
|
||||||
functions {
|
functions {
|
||||||
function percent() { if (!Number(max)) { return 0 } return Math.max(0, Math.min(100, Math.round(Number(currentValue) / Number(max) * 100))) }
|
shared function percent() { if (!Number(max)) { return 0 } return Math.max(0, Math.min(100, Math.round(Number(currentValue) / Number(max) * 100))) }
|
||||||
function detail(sourceEvent) { return { value: currentValue, max: max, percent: percent(), status: currentStatus, fileName: fileName, sourceEvent: sourceEvent } }
|
client function detail(sourceEvent) { return { value: currentValue, max: max, percent: percent(), status: currentStatus, fileName: fileName, sourceEvent: sourceEvent } }
|
||||||
function cancelUpload(sourceEvent) { currentStatus = "cancelled"; $emit("cancel", detail(sourceEvent)) }
|
client function cancelUpload(sourceEvent) { currentStatus = "cancelled"; output.cancel(detail(sourceEvent)) }
|
||||||
function retryUpload(sourceEvent) { currentValue = 0; currentStatus = "uploading"; $emit("retry", detail(sourceEvent)) }
|
client function retryUpload(sourceEvent) { currentValue = 0; currentStatus = "uploading"; output.retry(detail(sourceEvent)) }
|
||||||
function completeUpload(sourceEvent) { currentValue = max; currentStatus = "complete"; $emit("complete", detail(sourceEvent)) }
|
client function completeUpload(sourceEvent) { currentValue = max; currentStatus = "complete"; output.complete(detail(sourceEvent)) }
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload-progress {class}" data-status="{currentStatus}" aria-live="polite">
|
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--file-upload-progress {class}" data-status="{currentStatus}" aria-live="polite">
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
component Image {
|
component Image {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
src = ""
|
src: string = ""
|
||||||
alt = ""
|
alt: string = ""
|
||||||
width = ""
|
width: string = ""
|
||||||
height = ""
|
height: string = ""
|
||||||
loading = "lazy"
|
loading: string = "lazy"
|
||||||
rounded = false
|
rounded: boolean = false
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,39 +1,42 @@
|
|||||||
component InputGroup {
|
component InputGroup {
|
||||||
|
outputs {
|
||||||
|
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
focus(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
blur(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
submit(payload: { value: string | number | boolean | null | object; name: string; sourceEvent: Event })
|
||||||
|
action(payload: { name: string; sourceEvent: Event })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event focus = function
|
id: string = ""
|
||||||
@event blur = function
|
name: string = ""
|
||||||
@event submit = function
|
label: string = "Input group"
|
||||||
@event action = function
|
hiddenLabel: boolean = false
|
||||||
size = "default"
|
value: string = ""
|
||||||
color = "primary"
|
placeholder: string = ""
|
||||||
id = ""
|
type: string = "text"
|
||||||
name = ""
|
startText: string = ""
|
||||||
label = "Input group"
|
endText: string = ""
|
||||||
hiddenLabel = false
|
icon: string = ""
|
||||||
value = ""
|
iconPosition: string = "start"
|
||||||
placeholder = ""
|
actionLabel: string = ""
|
||||||
type = "text"
|
helperText: string = ""
|
||||||
startText = ""
|
cornerHint: string = ""
|
||||||
endText = ""
|
error: string = ""
|
||||||
icon = ""
|
inline: boolean = false
|
||||||
iconPosition = "start"
|
variant: string = "normal"
|
||||||
actionLabel = ""
|
readonly: boolean = false
|
||||||
helperText = ""
|
disabled: boolean = false
|
||||||
cornerHint = ""
|
required: boolean = false
|
||||||
error = ""
|
class: string = ""
|
||||||
inline = false
|
|
||||||
variant = "normal"
|
|
||||||
readonly = false
|
|
||||||
disabled = false
|
|
||||||
required = false
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
functions {
|
functions {
|
||||||
function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); $emit(nameEvent, { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
|
client function emitField(nameEvent, sourceEvent) { sourceEvent.stopPropagation(); output[nameEvent]({ value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) }
|
||||||
function handleKeydown(sourceEvent) { if (sourceEvent.key === "Enter") { sourceEvent.stopPropagation(); $emit("submit", { value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) } }
|
client function handleKeydown(sourceEvent) { if (sourceEvent.key === "Enter") { sourceEvent.stopPropagation(); output.submit({ value: sourceEvent.currentTarget.value, name: name, sourceEvent: sourceEvent }) } }
|
||||||
function handleAction(sourceEvent) { $emit("action", { name: name, sourceEvent: sourceEvent }) }
|
client function handleAction(sourceEvent) { output.action({ name: name, sourceEvent: sourceEvent }) }
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input-group {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input-group {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||||
|
|||||||
@@ -1,62 +1,65 @@
|
|||||||
component InputNumber {
|
component InputNumber {
|
||||||
|
outputs {
|
||||||
|
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
increment(payload: { value: number; previousValue?: number; sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
decrement(payload: { value: number; previousValue?: number; sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
variant = "default"
|
variant: string = "default"
|
||||||
class = ""
|
class: string = ""
|
||||||
|
|
||||||
id = ""
|
id: string = ""
|
||||||
name = "quantity"
|
name: string = "quantity"
|
||||||
value = 0
|
value: number = 0
|
||||||
min = ""
|
min: string = ""
|
||||||
max = ""
|
max: string = ""
|
||||||
step = 1
|
step: number = 1
|
||||||
precision = "auto"
|
precision: string = "auto"
|
||||||
|
|
||||||
label = ""
|
label: string = ""
|
||||||
description = ""
|
description: string = ""
|
||||||
helpText = ""
|
helpText: string = ""
|
||||||
error = ""
|
error: string = ""
|
||||||
invalid = false
|
invalid: boolean = false
|
||||||
|
|
||||||
prefix = ""
|
prefix: string = ""
|
||||||
suffix = ""
|
suffix: string = ""
|
||||||
placeholder = ""
|
placeholder: string = ""
|
||||||
autocomplete = "off"
|
autocomplete: string = "off"
|
||||||
inputMode = "decimal"
|
inputMode: string = "decimal"
|
||||||
ariaLabel = ""
|
ariaLabel: string = ""
|
||||||
|
|
||||||
required = false
|
required: boolean = false
|
||||||
disabled = false
|
disabled: boolean = false
|
||||||
inputDisabled = false
|
inputDisabled: boolean = false
|
||||||
buttonsDisabled = false
|
buttonsDisabled: boolean = false
|
||||||
readonly = false
|
readonly: boolean = false
|
||||||
allowInput = true
|
allowInput: boolean = true
|
||||||
keyboard = true
|
keyboard: boolean = true
|
||||||
wheel = false
|
wheel: boolean = false
|
||||||
clamp = true
|
clamp: boolean = true
|
||||||
fullWidth = false
|
fullWidth: boolean = false
|
||||||
showButtons = true
|
showButtons: boolean = true
|
||||||
showValidationMessage = true
|
showValidationMessage: boolean = true
|
||||||
|
|
||||||
decrementLabel = "Decrease value"
|
decrementLabel: string = "Decrease value"
|
||||||
incrementLabel = "Increase value"
|
incrementLabel: string = "Increase value"
|
||||||
controlsLabel = "Quantity controls"
|
controlsLabel: string = "Quantity controls"
|
||||||
requiredMessage = "A value is required."
|
requiredMessage: string = "A value is required."
|
||||||
minMessage = "Value is below the minimum."
|
minMessage: string = "Value is below the minimum."
|
||||||
maxMessage = "Value is above the maximum."
|
maxMessage: string = "Value is above the maximum."
|
||||||
|
|
||||||
@event input = function
|
|
||||||
@event change = function
|
|
||||||
@event increment = function
|
|
||||||
@event decrement = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state currentValue = value
|
state currentValue = value
|
||||||
state committedValue = value
|
state committedValue = value
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function inputId() {
|
shared function inputId() {
|
||||||
if (id !== "") {
|
if (id !== "") {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
@@ -68,15 +71,15 @@ component InputNumber {
|
|||||||
return "input-number"
|
return "input-number"
|
||||||
}
|
}
|
||||||
|
|
||||||
function descriptionId() {
|
shared function descriptionId() {
|
||||||
return inputId() + "-description"
|
return inputId() + "-description"
|
||||||
}
|
}
|
||||||
|
|
||||||
function messageId() {
|
shared function messageId() {
|
||||||
return inputId() + "-message"
|
return inputId() + "-message"
|
||||||
}
|
}
|
||||||
|
|
||||||
function componentColor() {
|
shared function componentColor() {
|
||||||
if (color === "secondary") {
|
if (color === "secondary") {
|
||||||
return "var(--wire-color-secondary)"
|
return "var(--wire-color-secondary)"
|
||||||
}
|
}
|
||||||
@@ -100,23 +103,23 @@ component InputNumber {
|
|||||||
return "var(--wire-color-primary)"
|
return "var(--wire-color-primary)"
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasMin() {
|
shared function hasMin() {
|
||||||
return min !== "" && min !== null && min !== undefined
|
return min !== "" && min !== null && min !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasMax() {
|
shared function hasMax() {
|
||||||
return max !== "" && max !== null && max !== undefined
|
return max !== "" && max !== null && max !== undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBlank() {
|
shared function isBlank() {
|
||||||
return currentValue === "" || currentValue === null || currentValue === undefined
|
return currentValue === "" || currentValue === null || currentValue === undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizedStep() {
|
shared function normalizedStep() {
|
||||||
return Number(step) > 0 ? Number(step) : 1
|
return Number(step) > 0 ? Number(step) : 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function inferredPrecision() {
|
shared function inferredPrecision() {
|
||||||
if (precision !== "auto" && precision !== "") {
|
if (precision !== "auto" && precision !== "") {
|
||||||
return Math.max(0, Number(precision) || 0)
|
return Math.max(0, Number(precision) || 0)
|
||||||
}
|
}
|
||||||
@@ -128,15 +131,15 @@ component InputNumber {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function precisionFactor() {
|
shared function precisionFactor() {
|
||||||
return Math.pow(10, inferredPrecision())
|
return Math.pow(10, inferredPrecision())
|
||||||
}
|
}
|
||||||
|
|
||||||
function roundValue(nextValue) {
|
shared function roundValue(nextValue) {
|
||||||
return Math.round(Number(nextValue) * precisionFactor()) / precisionFactor()
|
return Math.round(Number(nextValue) * precisionFactor()) / precisionFactor()
|
||||||
}
|
}
|
||||||
|
|
||||||
function clampValue(nextValue) {
|
shared function clampValue(nextValue) {
|
||||||
nextValue = Number(nextValue)
|
nextValue = Number(nextValue)
|
||||||
|
|
||||||
if (hasMin() && nextValue < Number(min)) {
|
if (hasMin() && nextValue < Number(min)) {
|
||||||
@@ -150,15 +153,15 @@ component InputNumber {
|
|||||||
return roundValue(nextValue)
|
return roundValue(nextValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isBelowMin() {
|
shared function isBelowMin() {
|
||||||
return !isBlank() && hasMin() && Number(currentValue) < Number(min)
|
return !isBlank() && hasMin() && Number(currentValue) < Number(min)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAboveMax() {
|
shared function isAboveMax() {
|
||||||
return !isBlank() && hasMax() && Number(currentValue) > Number(max)
|
return !isBlank() && hasMax() && Number(currentValue) > Number(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isInvalid() {
|
shared function isInvalid() {
|
||||||
return (
|
return (
|
||||||
invalid ||
|
invalid ||
|
||||||
error !== "" ||
|
error !== "" ||
|
||||||
@@ -168,7 +171,7 @@ component InputNumber {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function validationMessage() {
|
shared function validationMessage() {
|
||||||
if (error !== "") {
|
if (error !== "") {
|
||||||
return error
|
return error
|
||||||
}
|
}
|
||||||
@@ -188,14 +191,14 @@ component InputNumber {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasMessage() {
|
shared function hasMessage() {
|
||||||
return (
|
return (
|
||||||
helpText !== "" ||
|
helpText !== "" ||
|
||||||
(showValidationMessage && isInvalid() && validationMessage() !== "")
|
(showValidationMessage && isInvalid() && validationMessage() !== "")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function describedBy() {
|
shared function describedBy() {
|
||||||
if (description !== "" && hasMessage()) {
|
if (description !== "" && hasMessage()) {
|
||||||
return descriptionId() + " " + messageId()
|
return descriptionId() + " " + messageId()
|
||||||
}
|
}
|
||||||
@@ -211,7 +214,7 @@ component InputNumber {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function decrementDisabled() {
|
shared function decrementDisabled() {
|
||||||
return (
|
return (
|
||||||
disabled ||
|
disabled ||
|
||||||
readonly ||
|
readonly ||
|
||||||
@@ -220,7 +223,7 @@ component InputNumber {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function incrementDisabled() {
|
shared function incrementDisabled() {
|
||||||
return (
|
return (
|
||||||
disabled ||
|
disabled ||
|
||||||
readonly ||
|
readonly ||
|
||||||
@@ -229,7 +232,7 @@ component InputNumber {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispatchInputNumberEvent(
|
client function dispatchInputNumberEvent(
|
||||||
sourceEvent,
|
sourceEvent,
|
||||||
eventName,
|
eventName,
|
||||||
action,
|
action,
|
||||||
@@ -262,7 +265,7 @@ component InputNumber {
|
|||||||
root.dispatchEvent(customEvent)
|
root.dispatchEvent(customEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyControlValue(nextValue, action, sourceEvent, previousValue) {
|
client function applyControlValue(nextValue, action, sourceEvent, previousValue) {
|
||||||
previousValue = currentValue
|
previousValue = currentValue
|
||||||
currentValue = clampValue(nextValue)
|
currentValue = clampValue(nextValue)
|
||||||
committedValue = currentValue
|
committedValue = currentValue
|
||||||
@@ -287,7 +290,7 @@ component InputNumber {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function incrementValue(sourceEvent, nextValue) {
|
client function incrementValue(sourceEvent, nextValue) {
|
||||||
if (incrementDisabled()) {
|
if (incrementDisabled()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -303,7 +306,7 @@ component InputNumber {
|
|||||||
applyControlValue(nextValue, "increment", sourceEvent)
|
applyControlValue(nextValue, "increment", sourceEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function decrementValue(sourceEvent, nextValue) {
|
client function decrementValue(sourceEvent, nextValue) {
|
||||||
if (decrementDisabled()) {
|
if (decrementDisabled()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -319,7 +322,7 @@ component InputNumber {
|
|||||||
applyControlValue(nextValue, "decrement", sourceEvent)
|
applyControlValue(nextValue, "decrement", sourceEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInput(sourceEvent, previousValue, nextValue) {
|
client function handleInput(sourceEvent, previousValue, nextValue) {
|
||||||
sourceEvent.stopPropagation()
|
sourceEvent.stopPropagation()
|
||||||
previousValue = currentValue
|
previousValue = currentValue
|
||||||
nextValue = sourceEvent.target.value
|
nextValue = sourceEvent.target.value
|
||||||
@@ -338,7 +341,7 @@ component InputNumber {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleChange(sourceEvent, previousValue) {
|
client function handleChange(sourceEvent, previousValue) {
|
||||||
sourceEvent.stopPropagation()
|
sourceEvent.stopPropagation()
|
||||||
previousValue = committedValue
|
previousValue = committedValue
|
||||||
|
|
||||||
@@ -358,7 +361,7 @@ component InputNumber {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleKeydown(sourceEvent) {
|
client function handleKeydown(sourceEvent) {
|
||||||
if (
|
if (
|
||||||
!keyboard ||
|
!keyboard ||
|
||||||
disabled ||
|
disabled ||
|
||||||
@@ -384,7 +387,7 @@ component InputNumber {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleWheel(sourceEvent) {
|
client function handleWheel(sourceEvent) {
|
||||||
if (
|
if (
|
||||||
!wheel ||
|
!wheel ||
|
||||||
disabled ||
|
disabled ||
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
component Kbd {
|
component Kbd {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
label = "⌘ K"
|
label: string = "⌘ K"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
view { <kbd class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--kbd {class}"><slot>{label}</slot></kbd> }
|
view { <kbd class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--kbd {class}"><slot>{label}</slot></kbd> }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
component LayoutSplitter {
|
component LayoutSplitter {
|
||||||
|
outputs {
|
||||||
|
resizeStart(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
resize(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
resizeEnd(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event resizeStart = function
|
size: string = "default"
|
||||||
@event resize = function
|
color: string = "primary"
|
||||||
@event resizeEnd = function
|
columns: number = 2
|
||||||
size = "default"
|
gap: string = "md"
|
||||||
color = "primary"
|
maxWidth: string = "xl"
|
||||||
columns = 2
|
class: string = ""
|
||||||
gap = "md"
|
|
||||||
maxWidth = "xl"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--layout-splitter wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}"><slot /></div>
|
<div class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--layout-splitter wire-next--gap-{gap} wire-next--columns-{columns} wire-next--max-{maxWidth} {class}"><slot /></div>
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
component LegendIndicator {
|
component LegendIndicator {
|
||||||
|
outputs {
|
||||||
|
toggle(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event toggle = function
|
size: string = "default"
|
||||||
@event select = function
|
color: string = "primary"
|
||||||
size = "default"
|
title: string = "Legend Indicator"
|
||||||
color = "primary"
|
description: string = ""
|
||||||
title = "Legend Indicator"
|
items: unknown[] = []
|
||||||
description = ""
|
variant: string = "default"
|
||||||
items = []
|
class: string = ""
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--legend-indicator wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--legend-indicator wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
component Link {
|
component Link {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
label = "Link"
|
label: string = "Link"
|
||||||
href = "#"
|
href: string = "#"
|
||||||
target = ""
|
target: string = ""
|
||||||
rel = ""
|
rel: string = ""
|
||||||
external = false
|
external: boolean = false
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
component List {
|
component List {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
title = "List"
|
title: string = "List"
|
||||||
description = ""
|
description: string = ""
|
||||||
items = []
|
items: unknown[] = []
|
||||||
variant = "default"
|
variant: string = "default"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
component ListGroup {
|
component ListGroup {
|
||||||
|
outputs {
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event select = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
size = "default"
|
title: string = "List Group"
|
||||||
color = "primary"
|
description: string = ""
|
||||||
title = "List Group"
|
items: unknown[] = []
|
||||||
description = ""
|
variant: string = "default"
|
||||||
items = []
|
class: string = ""
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--list-group wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--list-group wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
component Map {
|
component Map {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
title = "Map"
|
title: string = "Map"
|
||||||
description = ""
|
description: string = ""
|
||||||
items = []
|
items: unknown[] = []
|
||||||
variant = "default"
|
variant: string = "default"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
component Marquee {
|
component Marquee {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
title = "Marquee"
|
title: string = "Marquee"
|
||||||
description = ""
|
description: string = ""
|
||||||
items = []
|
items: unknown[] = []
|
||||||
variant = "default"
|
variant: string = "default"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
state paused = false
|
state paused: boolean = false
|
||||||
|
|
||||||
view {
|
view {
|
||||||
<section
|
<section
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
component MegaMenu {
|
component MegaMenu {
|
||||||
|
outputs {
|
||||||
|
open(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
close(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event open = function
|
size: string = "default"
|
||||||
@event close = function
|
color: string = "primary"
|
||||||
@event select = function
|
label: string = "Mega Menu"
|
||||||
size = "default"
|
items: unknown[] = []
|
||||||
color = "primary"
|
active: string = ""
|
||||||
label = "Mega Menu"
|
orientation: string = "horizontal"
|
||||||
items = []
|
class: string = ""
|
||||||
active = ""
|
|
||||||
orientation = "horizontal"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--mega-menu wire-next--{orientation} {class}" aria-label="{label}">
|
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--mega-menu wire-next--{orientation} {class}" aria-label="{label}">
|
||||||
|
|||||||
@@ -1,23 +1,608 @@
|
|||||||
component Modal {
|
component Modal {
|
||||||
props {
|
outputs {
|
||||||
@event open = function
|
open(payload: { sourceEvent: Event })
|
||||||
@event close = function
|
close(payload: { reason: string; sourceEvent: Event })
|
||||||
@event cancel = function
|
cancel(payload: { sourceEvent: Event })
|
||||||
@event confirm = function
|
confirm(payload: { sourceEvent: Event })
|
||||||
size = "default"
|
|
||||||
color = "primary"
|
|
||||||
title = "Modal"
|
|
||||||
description = ""
|
|
||||||
open = false
|
|
||||||
placement = "bottom"
|
|
||||||
closeLabel = "Close"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
|
||||||
|
open: boolean = false
|
||||||
|
defaultOpen: boolean = false
|
||||||
|
title: string = "Modal"
|
||||||
|
description: string = ""
|
||||||
|
icon: string = ""
|
||||||
|
label: string = "Modal dialog"
|
||||||
|
size: string = "md"
|
||||||
|
placement: string = "center"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "default"
|
||||||
|
showClose: boolean = true
|
||||||
|
closeLabel: string = "Close modal"
|
||||||
|
closeOnBackdrop: boolean = true
|
||||||
|
closeOnEscape: boolean = true
|
||||||
|
closeOnCancel: boolean = true
|
||||||
|
closeOnConfirm: boolean = false
|
||||||
|
showFooter: boolean = true
|
||||||
|
cancelLabel: string = "Cancel"
|
||||||
|
cancelIcon: string = ""
|
||||||
|
confirmLabel: string = "Confirm"
|
||||||
|
confirmIcon: string = ""
|
||||||
|
confirmDisabled: boolean = false
|
||||||
|
confirmLoading: boolean = false
|
||||||
|
destructive: boolean = false
|
||||||
|
triggerLabel: string = ""
|
||||||
|
triggerIcon: string = ""
|
||||||
|
scrollable: boolean = true
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
state visible = defaultOpen
|
||||||
|
|
||||||
|
functions {
|
||||||
|
shared function isOpen() {
|
||||||
|
return open || visible
|
||||||
|
}
|
||||||
|
|
||||||
|
client function showModal(sourceEvent) {
|
||||||
|
visible = true
|
||||||
|
output.open({ sourceEvent: sourceEvent })
|
||||||
|
}
|
||||||
|
|
||||||
|
client function hideModal(reason, sourceEvent) {
|
||||||
|
visible = false
|
||||||
|
output.close({
|
||||||
|
reason: reason,
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
client function cancelModal(sourceEvent) {
|
||||||
|
output.cancel({ sourceEvent: sourceEvent })
|
||||||
|
if (closeOnCancel) {
|
||||||
|
hideModal("cancel", sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client function confirmModal(sourceEvent) {
|
||||||
|
if (confirmDisabled || confirmLoading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
output.confirm({ sourceEvent: sourceEvent })
|
||||||
|
if (closeOnConfirm) {
|
||||||
|
hideModal("confirm", sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client function handleKeydown(sourceEvent) {
|
||||||
|
if (closeOnEscape && sourceEvent.key === "Escape") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
cancelModal(sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
<div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--modal wire-next--placement-{placement} {class}" role="dialog" aria-modal="true" aria-label="{title}">
|
<div
|
||||||
<header><strong>{title}</strong><button type="button" aria-label="{closeLabel}">×</button></header>
|
{...attrs}
|
||||||
{#if description}<p>{description}</p>{/if}
|
data-ui-component="Modal"
|
||||||
<slot />
|
data-open='{open || visible ? "true" : "false"}'
|
||||||
|
data-size='{size}'
|
||||||
|
data-placement='{placement}'
|
||||||
|
data-color='{color}'
|
||||||
|
data-variant='{variant}'
|
||||||
|
data-scrollable='{scrollable ? "true" : "false"}'
|
||||||
|
data-destructive='{destructive ? "true" : "false"}'
|
||||||
|
class='wire-modal {class}'
|
||||||
|
>
|
||||||
|
{#if triggerLabel}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-modal__trigger"
|
||||||
|
aria-haspopup="dialog"
|
||||||
|
aria-expanded='{open || visible ? "true" : "false"}'
|
||||||
|
@click='showModal(event)'
|
||||||
|
>
|
||||||
|
{#if triggerIcon}
|
||||||
|
<span
|
||||||
|
class='{triggerIcon}'
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
<span>{triggerLabel}</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="wire-modal__trigger-slot"
|
||||||
|
@click='showModal(event)'
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="trigger"
|
||||||
|
>
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="wire-modal__layer"
|
||||||
|
data-show='{open || visible}'
|
||||||
|
role="presentation"
|
||||||
|
@keydown='handleKeydown(event)'
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-modal__backdrop"
|
||||||
|
aria-label='{closeLabel}'
|
||||||
|
@click='if (closeOnBackdrop) { cancelModal(event) }'
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="wire-modal__panel"
|
||||||
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-label='{label || title}'
|
||||||
|
tabindex="-1"
|
||||||
|
>
|
||||||
|
<header
|
||||||
|
class="wire-modal__header"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="wire-modal__heading"
|
||||||
|
>
|
||||||
|
{#if icon}
|
||||||
|
<span
|
||||||
|
class='wire-modal__icon {icon}'
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="wire-modal__heading-copy"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="header"
|
||||||
|
>
|
||||||
|
</slot>
|
||||||
|
{#if title}
|
||||||
|
<h2>{title}</h2>
|
||||||
|
{/if}
|
||||||
|
{#if description}
|
||||||
|
<p>{description}</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if showClose}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-modal__close"
|
||||||
|
aria-label='{closeLabel}'
|
||||||
|
@click='hideModal("close-button", event)'
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="icon-[lucide--x]"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="wire-modal__body"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if showFooter}
|
||||||
|
<footer
|
||||||
|
class="wire-modal__footer"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="wire-modal__custom-footer"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="footer"
|
||||||
|
>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="wire-modal__actions"
|
||||||
|
>
|
||||||
|
{#if cancelLabel}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-modal__button wire-modal__button--secondary"
|
||||||
|
@click='cancelModal(event)'
|
||||||
|
>
|
||||||
|
{#if cancelIcon}
|
||||||
|
<span
|
||||||
|
class='{cancelIcon}'
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
<span>{cancelLabel}</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if confirmLabel}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-modal__button wire-modal__button--primary"
|
||||||
|
disabled='{confirmDisabled || confirmLoading}'
|
||||||
|
@click='confirmModal(event)'
|
||||||
|
>
|
||||||
|
{#if confirmLoading}
|
||||||
|
<span
|
||||||
|
class="wire-modal__spinner"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
{:else if confirmIcon}
|
||||||
|
<span
|
||||||
|
class='{confirmIcon}'
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
<span>{confirmLabel}</span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style {
|
||||||
|
.wire-modal {
|
||||||
|
--modal-accent: var(--wire-color-primary);
|
||||||
|
--modal-soft: var(--wire-color-primary-soft);
|
||||||
|
--modal-contrast: var(--wire-color-primary-contrast);
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-color="secondary"] {
|
||||||
|
--modal-accent: var(--wire-color-secondary);
|
||||||
|
--modal-soft: var(--wire-color-secondary-soft);
|
||||||
|
--modal-contrast: var(--wire-color-secondary-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-color="info"] {
|
||||||
|
--modal-accent: var(--wire-color-info);
|
||||||
|
--modal-soft: var(--wire-color-info-soft);
|
||||||
|
--modal-contrast: var(--wire-color-info-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-color="success"] {
|
||||||
|
--modal-accent: var(--wire-color-success);
|
||||||
|
--modal-soft: var(--wire-color-success-soft);
|
||||||
|
--modal-contrast: var(--wire-color-success-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-color="warning"] {
|
||||||
|
--modal-accent: var(--wire-color-warning);
|
||||||
|
--modal-soft: var(--wire-color-warning-soft);
|
||||||
|
--modal-contrast: var(--wire-color-warning-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-color="danger"],
|
||||||
|
.wire-modal[data-destructive="true"] {
|
||||||
|
--modal-accent: var(--wire-color-danger);
|
||||||
|
--modal-soft: var(--wire-color-danger-soft);
|
||||||
|
--modal-contrast: var(--wire-color-on-danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__trigger,
|
||||||
|
.wire-modal__trigger-slot {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.55rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__trigger {
|
||||||
|
appearance: none;
|
||||||
|
min-height: 2.55rem;
|
||||||
|
padding: 0.65rem 1rem;
|
||||||
|
color: var(--modal-contrast);
|
||||||
|
background: var(--modal-accent);
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0.8rem;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 650;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__layer {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1250;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-placement="top"] .wire-modal__layer {
|
||||||
|
align-items: flex-start;
|
||||||
|
padding-top: clamp(1rem, 8vh, 5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__backdrop {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
appearance: none;
|
||||||
|
padding: 0;
|
||||||
|
background: color-mix(in srgb, black 62%, transparent);
|
||||||
|
border: 0;
|
||||||
|
backdrop-filter: blur(9px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__panel {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: min(32rem, calc(100vw - 2rem));
|
||||||
|
max-height: min(88vh, 52rem);
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background:
|
||||||
|
radial-gradient(
|
||||||
|
circle at 100% 0%,
|
||||||
|
color-mix(in srgb, var(--modal-accent) 9%, transparent),
|
||||||
|
transparent 34%
|
||||||
|
),
|
||||||
|
var(--wire-color-surface-raised);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--modal-accent) 18%, var(--wire-color-border));
|
||||||
|
border-radius: 1.35rem;
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
|
||||||
|
0 40px 110px color-mix(in srgb, black 38%, transparent);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-size="sm"] .wire-modal__panel {
|
||||||
|
width: min(25rem, calc(100vw - 2rem));
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-size="lg"] .wire-modal__panel {
|
||||||
|
width: min(44rem, calc(100vw - 2rem));
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-size="xl"] .wire-modal__panel {
|
||||||
|
width: min(64rem, calc(100vw - 2rem));
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-size="full"] .wire-modal__panel {
|
||||||
|
width: calc(100vw - 2rem);
|
||||||
|
height: calc(100vh - 2rem);
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-variant="soft"] .wire-modal__panel {
|
||||||
|
background:
|
||||||
|
linear-gradient(145deg, var(--modal-soft), transparent 68%),
|
||||||
|
var(--wire-color-surface-raised);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-variant="outline"] .wire-modal__panel {
|
||||||
|
background: var(--wire-color-surface-raised);
|
||||||
|
box-shadow: 0 24px 72px color-mix(in srgb, black 24%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-variant="solid"] .wire-modal__panel {
|
||||||
|
color: var(--modal-contrast);
|
||||||
|
background: var(--modal-accent);
|
||||||
|
border-color: color-mix(in srgb, white 20%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1.4rem 1.4rem 1.15rem;
|
||||||
|
border-bottom: 1px solid var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__heading {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.9rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__icon {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 1.3rem;
|
||||||
|
height: 1.3rem;
|
||||||
|
margin-top: 0.15rem;
|
||||||
|
color: var(--modal-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-variant="solid"] .wire-modal__icon {
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__heading-copy {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.3rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__heading-copy h2,
|
||||||
|
.wire-modal__heading-copy p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__heading-copy h2 {
|
||||||
|
font-size: 1.08rem;
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__heading-copy p {
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-variant="solid"] .wire-modal__heading-copy p {
|
||||||
|
color: color-mix(in srgb, currentColor 76%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__close {
|
||||||
|
appearance: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 2.35rem;
|
||||||
|
height: 2.35rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
background: var(--wire-color-surface-soft);
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__close:hover,
|
||||||
|
.wire-modal__close:focus-visible {
|
||||||
|
color: var(--modal-accent);
|
||||||
|
border-color: color-mix(in srgb, var(--modal-accent) 34%, var(--wire-color-border));
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__body {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
padding: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal[data-scrollable="true"] .wire-modal__body {
|
||||||
|
overflow: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 1rem 1.4rem 1.4rem;
|
||||||
|
border-top: 1px solid var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__custom-footer:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 0.65rem;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__button {
|
||||||
|
appearance: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
min-height: 2.55rem;
|
||||||
|
padding: 0.65rem 1rem;
|
||||||
|
border-radius: 0.78rem;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.83rem;
|
||||||
|
font-weight: 650;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 150ms ease, opacity 150ms ease, border-color 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__button:active {
|
||||||
|
transform: scale(0.985);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__button--secondary {
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__button--primary {
|
||||||
|
color: var(--modal-contrast);
|
||||||
|
background: var(--modal-accent);
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__button:disabled {
|
||||||
|
opacity: 0.55;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__spinner {
|
||||||
|
width: 0.95rem;
|
||||||
|
height: 0.95rem;
|
||||||
|
border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
|
||||||
|
border-top-color: currentColor;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: wire-modal-spin 750ms linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes wire-modal-spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
.wire-modal__layer {
|
||||||
|
align-items: flex-end;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__panel,
|
||||||
|
.wire-modal[data-size="sm"] .wire-modal__panel,
|
||||||
|
.wire-modal[data-size="lg"] .wire-modal__panel,
|
||||||
|
.wire-modal[data-size="xl"] .wire-modal__panel {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 92vh;
|
||||||
|
border-radius: 1.25rem 1.25rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__footer {
|
||||||
|
align-items: stretch;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__actions {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-modal__button {
|
||||||
|
flex: 1 1 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.wire-modal__button,
|
||||||
|
.wire-modal__spinner {
|
||||||
|
animation: none;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
component Nav {
|
component Nav {
|
||||||
|
outputs {
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event select = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
size = "default"
|
label: string = "Nav"
|
||||||
color = "primary"
|
items: unknown[] = []
|
||||||
label = "Nav"
|
active: string = ""
|
||||||
items = []
|
orientation: string = "horizontal"
|
||||||
active = ""
|
class: string = ""
|
||||||
orientation = "horizontal"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--nav wire-next--{orientation} {class}" aria-label="{label}">
|
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--nav wire-next--{orientation} {class}" aria-label="{label}">
|
||||||
|
|||||||
@@ -1,45 +1,48 @@
|
|||||||
component Navbar {
|
component Navbar {
|
||||||
props {
|
outputs {
|
||||||
@event toggle = function
|
toggle(payload: { open: boolean })
|
||||||
@event open = function
|
open(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event close = function
|
close(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event select = function
|
select(payload: { item: string | number | boolean | null | object; value: string | number | boolean; level: string })
|
||||||
@event action = function
|
action(payload: { item: string | number | boolean | null | object; value: string | number | boolean })
|
||||||
size = "default"
|
|
||||||
color = "primary"
|
|
||||||
label = "Primary navigation"
|
|
||||||
topbarLabel = "Utility navigation"
|
|
||||||
brand = {}
|
|
||||||
items = []
|
|
||||||
actions = []
|
|
||||||
active = ""
|
|
||||||
sticky = false
|
|
||||||
openOnHover = false
|
|
||||||
maxWidth = "full"
|
|
||||||
mobileLabel = "Toggle navigation"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state mobileOpen = false
|
props {
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
label: string = "Primary navigation"
|
||||||
|
topbarLabel: string = "Utility navigation"
|
||||||
|
brand: Record<string, unknown> = {}
|
||||||
|
items: unknown[] = []
|
||||||
|
actions: unknown[] = []
|
||||||
|
active: string = ""
|
||||||
|
sticky: boolean = false
|
||||||
|
openOnHover: boolean = false
|
||||||
|
maxWidth: string = "full"
|
||||||
|
mobileLabel: string = "Toggle navigation"
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
state mobileOpen: boolean = false
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function toggleNavigation() {
|
client function toggleNavigation() {
|
||||||
mobileOpen = !mobileOpen
|
mobileOpen = !mobileOpen
|
||||||
$emit("toggle", { open: mobileOpen })
|
output.toggle({ open: mobileOpen })
|
||||||
$emit(mobileOpen ? "open" : "close", { source: "mobile" })
|
output[mobileOpen ? "open" : "close"]({ source: "mobile" })
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectItem(item, level) {
|
client function selectItem(item, level) {
|
||||||
mobileOpen = false
|
mobileOpen = false
|
||||||
$emit("select", { item: item, value: item.value || "", level: level })
|
output.select({ item: item, value: item.value || "", level: level })
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectAction(item) {
|
client function selectAction(item) {
|
||||||
mobileOpen = false
|
mobileOpen = false
|
||||||
$emit("action", { item: item, value: item.value || "" })
|
output.action({ item: item, value: item.value || "" })
|
||||||
}
|
}
|
||||||
|
|
||||||
function isItemActive(item) {
|
shared function isItemActive(item) {
|
||||||
if (!item) return false
|
if (!item) return false
|
||||||
if (item.value && item.value === active) return true
|
if (item.value && item.value === active) return true
|
||||||
if (!item.children || !item.children.length) return false
|
if (!item.children || !item.children.length) return false
|
||||||
@@ -48,8 +51,8 @@ component Navbar {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleDropdown(event, item) {
|
client function toggleDropdown(event, item) {
|
||||||
$emit(event.currentTarget.open ? "open" : "close", {
|
output[event.currentTarget.open ? "open" : "close"]({
|
||||||
source: "menu",
|
source: "menu",
|
||||||
item: item
|
item: item
|
||||||
})
|
})
|
||||||
@@ -86,7 +89,7 @@ component Navbar {
|
|||||||
<nav class="wire-navbar__menus" aria-label="{label}">
|
<nav class="wire-navbar__menus" aria-label="{label}">
|
||||||
{#each items as item}
|
{#each items as item}
|
||||||
{#if item.children && item.children.length}
|
{#if item.children && item.children.length}
|
||||||
<details class="wire-navbar__dropdown wire-navbar__dropdown--{item.type || 'dropdown'}" name="wire-navbar-menu" @toggle="toggleDropdown($event, item)">
|
<details class="wire-navbar__dropdown wire-navbar__dropdown--{item.type || 'dropdown'}" name="wire-navbar-menu" @toggle="toggleDropdown(event, item)">
|
||||||
<summary aria-current="{isItemActive(item) ? 'page' : ''}">
|
<summary aria-current="{isItemActive(item) ? 'page' : ''}">
|
||||||
{#if item.icon}<span class="{item.icon}" aria-hidden="true"></span>{/if}
|
{#if item.icon}<span class="{item.icon}" aria-hidden="true"></span>{/if}
|
||||||
<span>{item.label}</span>
|
<span>{item.label}</span>
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
component Pagination {
|
component Pagination {
|
||||||
|
outputs {
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
previous(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
next(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event change = function
|
size: string = "default"
|
||||||
@event previous = function
|
color: string = "primary"
|
||||||
@event next = function
|
label: string = "Pagination"
|
||||||
size = "default"
|
items: unknown[] = []
|
||||||
color = "primary"
|
active: string = ""
|
||||||
label = "Pagination"
|
orientation: string = "horizontal"
|
||||||
items = []
|
class: string = ""
|
||||||
active = ""
|
|
||||||
orientation = "horizontal"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--pagination wire-next--{orientation} {class}" aria-label="{label}">
|
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--pagination wire-next--{orientation} {class}" aria-label="{label}">
|
||||||
|
|||||||
@@ -1,41 +1,44 @@
|
|||||||
component PinInput {
|
component PinInput {
|
||||||
|
outputs {
|
||||||
|
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
complete(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
paste(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
clear(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
label = "Verification code"
|
label: string = "Verification code"
|
||||||
name = "pin"
|
name: string = "pin"
|
||||||
value = ""
|
value: string = ""
|
||||||
length = 4
|
length: number = 4
|
||||||
pattern = "[0-9]"
|
pattern: string = "[0-9]"
|
||||||
type = "text"
|
type: string = "text"
|
||||||
inputMode = "numeric"
|
inputMode: string = "numeric"
|
||||||
placeholder = "○"
|
placeholder: string = "○"
|
||||||
autocomplete = "one-time-code"
|
autocomplete: string = "one-time-code"
|
||||||
masked = false
|
masked: boolean = false
|
||||||
disabled = false
|
disabled: boolean = false
|
||||||
readonly = false
|
readonly: boolean = false
|
||||||
required = false
|
required: boolean = false
|
||||||
autoFocus = false
|
autoFocus: boolean = false
|
||||||
autoSubmit = false
|
autoSubmit: boolean = false
|
||||||
allowPaste = true
|
allowPaste: boolean = true
|
||||||
clearable = true
|
clearable: boolean = true
|
||||||
clearLabel = "Clear code"
|
clearLabel: string = "Clear code"
|
||||||
separator = ""
|
separator: string = ""
|
||||||
groupSize = 0
|
groupSize: number = 0
|
||||||
helpText = ""
|
helpText: string = ""
|
||||||
invalid = false
|
invalid: boolean = false
|
||||||
validationMessage = ""
|
validationMessage: string = ""
|
||||||
class = ""
|
class: string = ""
|
||||||
@event input = function
|
|
||||||
@event change = function
|
|
||||||
@event complete = function
|
|
||||||
@event paste = function
|
|
||||||
@event clear = function
|
|
||||||
@event error = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function inputIndexes() {
|
shared function inputIndexes() {
|
||||||
return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].slice(
|
return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].slice(
|
||||||
0,
|
0,
|
||||||
Math.max(1, Math.min(12, Number(length)))
|
Math.max(1, Math.min(12, Number(length)))
|
||||||
|
|||||||
@@ -1,21 +1,536 @@
|
|||||||
component Popover {
|
component Popover {
|
||||||
props {
|
outputs {
|
||||||
@event open = function
|
toggle(payload: { open: boolean; sourceEvent: Event; reason?: object })
|
||||||
@event close = function
|
open(payload: { sourceEvent: Event })
|
||||||
size = "default"
|
close(payload: { reason: string; sourceEvent: Event })
|
||||||
color = "primary"
|
action(payload: { href: string; sourceEvent: Event })
|
||||||
title = "Popover"
|
|
||||||
description = ""
|
|
||||||
open = false
|
|
||||||
placement = "bottom"
|
|
||||||
closeLabel = "Close"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
|
||||||
|
open: boolean = false
|
||||||
|
defaultOpen: boolean = false
|
||||||
|
triggerLabel: string = "Open popover"
|
||||||
|
triggerIcon: string = ""
|
||||||
|
title: string = ""
|
||||||
|
description: string = ""
|
||||||
|
icon: string = ""
|
||||||
|
placement: string = "bottom-start"
|
||||||
|
width: string = "md"
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "raised"
|
||||||
|
showArrow: boolean = true
|
||||||
|
showClose: boolean = false
|
||||||
|
closeLabel: string = "Close popover"
|
||||||
|
closeOnOutside: boolean = true
|
||||||
|
closeOnEscape: boolean = true
|
||||||
|
actionLabel: string = ""
|
||||||
|
actionHref: string = ""
|
||||||
|
actionIcon: string = ""
|
||||||
|
closeOnAction: boolean = true
|
||||||
|
disabled: boolean = false
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
state visible = defaultOpen
|
||||||
|
|
||||||
|
functions {
|
||||||
|
shared function isOpen() {
|
||||||
|
return open || visible
|
||||||
|
}
|
||||||
|
|
||||||
|
client function showPopover(sourceEvent) {
|
||||||
|
if (disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
visible = true
|
||||||
|
output.open({ sourceEvent: sourceEvent })
|
||||||
|
output.toggle({ open: true, sourceEvent: sourceEvent })
|
||||||
|
}
|
||||||
|
|
||||||
|
client function hidePopover(reason, sourceEvent) {
|
||||||
|
visible = false
|
||||||
|
output.close({ reason: reason, sourceEvent: sourceEvent })
|
||||||
|
output.toggle({ open: false, reason: reason, sourceEvent: sourceEvent })
|
||||||
|
}
|
||||||
|
|
||||||
|
client function togglePopover(sourceEvent) {
|
||||||
|
if (isOpen()) {
|
||||||
|
hidePopover("toggle", sourceEvent)
|
||||||
|
} else {
|
||||||
|
showPopover(sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client function activateAction(sourceEvent) {
|
||||||
|
output.action({
|
||||||
|
href: actionHref,
|
||||||
|
sourceEvent: sourceEvent
|
||||||
|
})
|
||||||
|
if (closeOnAction) {
|
||||||
|
hidePopover("action", sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client function handleKeydown(sourceEvent) {
|
||||||
|
if (closeOnEscape && sourceEvent.key === "Escape") {
|
||||||
|
sourceEvent.preventDefault()
|
||||||
|
hidePopover("escape", sourceEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
<div data-show="{open}" class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--popover wire-next--placement-{placement} {class}" role="region" aria-modal="false" aria-label="{title}">
|
<div
|
||||||
<header><strong>{title}</strong><button type="button" aria-label="{closeLabel}">×</button></header>
|
{...attrs}
|
||||||
{#if description}<p>{description}</p>{/if}
|
data-ui-component="Popover"
|
||||||
<slot />
|
data-open='{open || visible ? "true" : "false"}'
|
||||||
|
data-placement='{placement}'
|
||||||
|
data-width='{width}'
|
||||||
|
data-size='{size}'
|
||||||
|
data-color='{color}'
|
||||||
|
data-variant='{variant}'
|
||||||
|
class='wire-popover {class}'
|
||||||
|
@keydown='handleKeydown(event)'
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-popover__trigger"
|
||||||
|
disabled='{disabled}'
|
||||||
|
aria-haspopup="dialog"
|
||||||
|
aria-expanded='{open || visible ? "true" : "false"}'
|
||||||
|
@click='togglePopover(event)'
|
||||||
|
>
|
||||||
|
<slot name="trigger"></slot>
|
||||||
|
{#if triggerIcon}
|
||||||
|
<span class='{triggerIcon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
{#if triggerLabel}
|
||||||
|
<span>{triggerLabel}</span>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{#if closeOnOutside}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-popover__dismiss-layer"
|
||||||
|
data-show='{open || visible}'
|
||||||
|
aria-label='{closeLabel}'
|
||||||
|
@click='hidePopover("outside", event)'
|
||||||
|
></button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="wire-popover__panel"
|
||||||
|
data-show='{open || visible}'
|
||||||
|
role="dialog"
|
||||||
|
aria-label='{title || triggerLabel}'
|
||||||
|
>
|
||||||
|
{#if showArrow}
|
||||||
|
<span class="wire-popover__arrow" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if title || description || icon || showClose}
|
||||||
|
<header class="wire-popover__header">
|
||||||
|
<div class="wire-popover__heading">
|
||||||
|
{#if icon}
|
||||||
|
<span class='wire-popover__icon {icon}' aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
<div class="wire-popover__heading-copy">
|
||||||
|
<slot name="header"></slot>
|
||||||
|
{#if title}
|
||||||
|
<h3>{title}</h3>
|
||||||
|
{/if}
|
||||||
|
{#if description}
|
||||||
|
<p>{description}</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if showClose}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-popover__close"
|
||||||
|
aria-label='{closeLabel}'
|
||||||
|
@click='hidePopover("close-button", event)'
|
||||||
|
>
|
||||||
|
<span class="icon-[lucide--x]" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</header>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="wire-popover__body">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if actionLabel}
|
||||||
|
<footer class="wire-popover__footer">
|
||||||
|
{#if actionHref}
|
||||||
|
<a
|
||||||
|
href='{actionHref}'
|
||||||
|
class="wire-popover__action"
|
||||||
|
@click='activateAction(event)'
|
||||||
|
>
|
||||||
|
<span>{actionLabel}</span>
|
||||||
|
{#if actionIcon}
|
||||||
|
<span class='{actionIcon}' aria-hidden="true"></span>
|
||||||
|
{:else}
|
||||||
|
<span class="icon-[lucide--arrow-right]" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="wire-popover__action"
|
||||||
|
@click='activateAction(event)'
|
||||||
|
>
|
||||||
|
<span>{actionLabel}</span>
|
||||||
|
{#if actionIcon}
|
||||||
|
<span class='{actionIcon}' aria-hidden="true"></span>
|
||||||
|
{:else}
|
||||||
|
<span class="icon-[lucide--arrow-right]" aria-hidden="true"></span>
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</footer>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<slot name="footer"></slot>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style {
|
||||||
|
.wire-popover {
|
||||||
|
--popover-accent: var(--wire-color-primary);
|
||||||
|
--popover-soft: var(--wire-color-primary-soft);
|
||||||
|
--popover-contrast: var(--wire-color-primary-contrast);
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-color="secondary"] {
|
||||||
|
--popover-accent: var(--wire-color-secondary);
|
||||||
|
--popover-soft: var(--wire-color-secondary-soft);
|
||||||
|
--popover-contrast: var(--wire-color-secondary-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-color="info"] {
|
||||||
|
--popover-accent: var(--wire-color-info);
|
||||||
|
--popover-soft: var(--wire-color-info-soft);
|
||||||
|
--popover-contrast: var(--wire-color-info-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-color="success"] {
|
||||||
|
--popover-accent: var(--wire-color-success);
|
||||||
|
--popover-soft: var(--wire-color-success-soft);
|
||||||
|
--popover-contrast: var(--wire-color-success-contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-color="warning"] {
|
||||||
|
--popover-accent: var(--wire-color-warning);
|
||||||
|
--popover-soft: var(--wire-color-warning-soft);
|
||||||
|
--popover-contrast: var(--wire-color-warning-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-color="danger"] {
|
||||||
|
--popover-accent: var(--wire-color-danger);
|
||||||
|
--popover-soft: var(--wire-color-danger-soft);
|
||||||
|
--popover-contrast: var(--wire-color-on-danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__trigger {
|
||||||
|
appearance: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.55rem;
|
||||||
|
min-height: 2.55rem;
|
||||||
|
padding: 0.65rem 0.9rem;
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background: var(--wire-color-surface-raised);
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
border-radius: 0.78rem;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.84rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__trigger:hover,
|
||||||
|
.wire-popover__trigger:focus-visible,
|
||||||
|
.wire-popover[data-open="true"] .wire-popover__trigger {
|
||||||
|
color: var(--popover-accent);
|
||||||
|
background: var(--popover-soft);
|
||||||
|
border-color: color-mix(in srgb, var(--popover-accent) 38%, var(--wire-color-border));
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__trigger:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-size="sm"] .wire-popover__trigger {
|
||||||
|
min-height: 2.2rem;
|
||||||
|
padding: 0.5rem 0.72rem;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-size="lg"] .wire-popover__trigger {
|
||||||
|
min-height: 2.9rem;
|
||||||
|
padding: 0.78rem 1.05rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__dismiss-layer {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 1120;
|
||||||
|
appearance: none;
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__panel {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1121;
|
||||||
|
top: calc(100% + 0.72rem);
|
||||||
|
left: 0;
|
||||||
|
width: 18rem;
|
||||||
|
max-width: calc(100vw - 1.5rem);
|
||||||
|
color: var(--wire-color-text);
|
||||||
|
background:
|
||||||
|
linear-gradient(145deg, color-mix(in srgb, var(--popover-accent) 5%, transparent), transparent 62%),
|
||||||
|
color-mix(in srgb, var(--wire-color-surface-raised) 97%, transparent);
|
||||||
|
border: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow:
|
||||||
|
0 1px 0 color-mix(in srgb, white 5%, transparent) inset,
|
||||||
|
0 24px 64px color-mix(in srgb, black 22%, transparent);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-width="sm"] .wire-popover__panel {
|
||||||
|
width: 14rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-width="lg"] .wire-popover__panel {
|
||||||
|
width: 24rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-width="xl"] .wire-popover__panel {
|
||||||
|
width: 32rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-width="trigger"] .wire-popover__panel {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="bottom-end"] .wire-popover__panel {
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="top-start"] .wire-popover__panel {
|
||||||
|
top: auto;
|
||||||
|
bottom: calc(100% + 0.72rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="top-end"] .wire-popover__panel {
|
||||||
|
top: auto;
|
||||||
|
right: 0;
|
||||||
|
bottom: calc(100% + 0.72rem);
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="left"] .wire-popover__panel {
|
||||||
|
top: 50%;
|
||||||
|
right: calc(100% + 0.72rem);
|
||||||
|
left: auto;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="right"] .wire-popover__panel {
|
||||||
|
top: 50%;
|
||||||
|
left: calc(100% + 0.72rem);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-variant="soft"] .wire-popover__panel {
|
||||||
|
background:
|
||||||
|
linear-gradient(145deg, var(--popover-soft), transparent 70%),
|
||||||
|
var(--wire-color-surface-raised);
|
||||||
|
box-shadow: 0 18px 48px color-mix(in srgb, black 16%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-variant="outline"] .wire-popover__panel {
|
||||||
|
background: var(--wire-color-surface-raised);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-variant="solid"] .wire-popover__panel {
|
||||||
|
color: var(--popover-contrast);
|
||||||
|
background: var(--popover-accent);
|
||||||
|
border-color: color-mix(in srgb, white 20%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__arrow {
|
||||||
|
position: absolute;
|
||||||
|
top: -0.35rem;
|
||||||
|
left: 1.25rem;
|
||||||
|
width: 0.7rem;
|
||||||
|
height: 0.7rem;
|
||||||
|
background: inherit;
|
||||||
|
border-top: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
|
||||||
|
border-left: 1px solid color-mix(in srgb, var(--popover-accent) 18%, var(--wire-color-border));
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="bottom-end"] .wire-popover__arrow {
|
||||||
|
right: 1.25rem;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="top-start"] .wire-popover__arrow,
|
||||||
|
.wire-popover[data-placement="top-end"] .wire-popover__arrow {
|
||||||
|
top: auto;
|
||||||
|
bottom: -0.35rem;
|
||||||
|
transform: rotate(225deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="left"] .wire-popover__arrow {
|
||||||
|
top: 50%;
|
||||||
|
right: -0.35rem;
|
||||||
|
left: auto;
|
||||||
|
transform: translateY(-50%) rotate(135deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-placement="right"] .wire-popover__arrow {
|
||||||
|
top: 50%;
|
||||||
|
left: -0.35rem;
|
||||||
|
transform: translateY(-50%) rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.8rem;
|
||||||
|
padding: 1rem 1rem 0.8rem;
|
||||||
|
border-bottom: 1px solid var(--wire-color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__heading {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.7rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__icon {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 1.05rem;
|
||||||
|
height: 1.05rem;
|
||||||
|
margin-top: 0.15rem;
|
||||||
|
color: var(--popover-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-variant="solid"] .wire-popover__icon {
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__heading-copy {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.2rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__heading-copy h3,
|
||||||
|
.wire-popover__heading-copy p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__heading-copy h3 {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 650;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__heading-copy p {
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.74rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover[data-variant="solid"] .wire-popover__heading-copy p {
|
||||||
|
color: color-mix(in srgb, currentColor 76%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__close {
|
||||||
|
appearance: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
background: var(--wire-color-surface-soft);
|
||||||
|
border: 1px solid var(--wire-color-border);
|
||||||
|
border-radius: 0.65rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__body {
|
||||||
|
padding: 1rem;
|
||||||
|
color: var(--wire-color-text-muted);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__footer {
|
||||||
|
padding: 0 1rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__action {
|
||||||
|
appearance: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.45rem;
|
||||||
|
min-height: 2.35rem;
|
||||||
|
padding: 0.58rem 0.8rem;
|
||||||
|
color: var(--popover-contrast);
|
||||||
|
background: var(--popover-accent);
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0.7rem;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
font-weight: 650;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 639px) {
|
||||||
|
.wire-popover__panel {
|
||||||
|
position: fixed;
|
||||||
|
right: 0.75rem;
|
||||||
|
bottom: 0.75rem;
|
||||||
|
left: 0.75rem;
|
||||||
|
top: auto;
|
||||||
|
width: auto;
|
||||||
|
max-width: none;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wire-popover__arrow {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,52 @@
|
|||||||
component RangeSlider {
|
component RangeSlider {
|
||||||
|
outputs {
|
||||||
|
input(payload: ({ value: number; name: string; sourceEvent: Event }) | ({ sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[]))
|
||||||
|
change(payload: ({ value: number; name: string; sourceEvent: Event }) | ({ sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[]))
|
||||||
|
focus(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
blur(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event focus = function
|
id: string = ""
|
||||||
@event blur = function
|
name: string = ""
|
||||||
size = "default"
|
label: string = "Range"
|
||||||
color = "primary"
|
hiddenLabel: boolean = false
|
||||||
id = ""
|
placeholder: string = ""
|
||||||
name = ""
|
variant: string = "normal"
|
||||||
label = "Range"
|
icon: string = ""
|
||||||
hiddenLabel = false
|
iconPosition: string = "start"
|
||||||
placeholder = ""
|
value: number = 50
|
||||||
variant = "normal"
|
min: number = 0
|
||||||
icon = ""
|
max: number = 100
|
||||||
iconPosition = "start"
|
step: number = 1
|
||||||
value = 50
|
showValue: boolean = true
|
||||||
min = 0
|
showBounds: boolean = true
|
||||||
max = 100
|
showSteps: boolean = false
|
||||||
step = 1
|
marks: unknown[] = []
|
||||||
showValue = true
|
helperText: string = ""
|
||||||
showBounds = true
|
cornerHint: string = ""
|
||||||
showSteps = false
|
error: string = ""
|
||||||
marks = []
|
inline: boolean = false
|
||||||
helperText = ""
|
readonly: boolean = false
|
||||||
cornerHint = ""
|
disabled: boolean = false
|
||||||
error = ""
|
required: boolean = false
|
||||||
inline = false
|
class: string = ""
|
||||||
readonly = false
|
|
||||||
disabled = false
|
|
||||||
required = false
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
state currentValue = value
|
state currentValue = value
|
||||||
functions {
|
functions {
|
||||||
function percent() { if (Number(max) === Number(min)) { return 0 } return (Number(currentValue) - Number(min)) / (Number(max) - Number(min)) * 100 }
|
shared function percent() { if (Number(max) === Number(min)) { return 0 } return (Number(currentValue) - Number(min)) / (Number(max) - Number(min)) * 100 }
|
||||||
function setValue(nextValue, sourceEvent, commit, detail, root, slider, input, output, progressValue) { if (readonly || disabled) { return } currentValue = Number(nextValue); root = sourceEvent.currentTarget.closest(".wire-next--range-slider"); if (root) { slider = root.querySelector("[role=slider]"); input = root.querySelector("input[name='" + name + "']"); output = root.querySelector("output"); progressValue = (currentValue - Number(min)) / (Number(max) - Number(min)) * 100; if (slider) { slider.setAttribute("aria-valuenow", String(currentValue)); slider.style.setProperty("--wire-range-progress", progressValue + "%") } if (input) { input.value = String(currentValue) } if (output) { output.textContent = String(currentValue) } } detail = { value: currentValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; $emit("input", detail); if (commit) { $emit("change", detail) } }
|
client function setValue(nextValue, sourceEvent, commit, detail, root, slider, input, outputElement, progressValue) { if (readonly || disabled) { return } currentValue = Number(nextValue); root = sourceEvent.currentTarget.closest(".wire-next--range-slider"); if (root) { slider = root.querySelector("[role=slider]"); input = root.querySelector("input[name='" + name + "']"); outputElement = root.querySelector("output"); progressValue = (currentValue - Number(min)) / (Number(max) - Number(min)) * 100; if (slider) { slider.setAttribute("aria-valuenow", String(currentValue)); slider.style.setProperty("--wire-range-progress", progressValue + "%") } if (input) { input.value = String(currentValue) } if (outputElement) { outputElement.textContent = String(currentValue) } } detail = { value: currentValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; output.input(detail); if (commit) { output.change(detail) } }
|
||||||
function valueFromPointer(sourceEvent, rect, ratio) { rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); return Number(min) + ratio * (Number(max) - Number(min)) }
|
client function valueFromPointer(sourceEvent, rect, ratio) { rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); return Number(min) + ratio * (Number(max) - Number(min)) }
|
||||||
function beginSlide(sourceEvent, rect, ratio, rawValue) { if (readonly || disabled) { return } sourceEvent.currentTarget.setPointerCapture(sourceEvent.pointerId); rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function beginSlide(sourceEvent, rect, ratio, rawValue) { if (readonly || disabled) { return } sourceEvent.currentTarget.setPointerCapture(sourceEvent.pointerId); rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function moveSlide(sourceEvent, rect, ratio, rawValue) { if (!sourceEvent.currentTarget.hasPointerCapture(sourceEvent.pointerId)) { return } rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function moveSlide(sourceEvent, rect, ratio, rawValue) { if (!sourceEvent.currentTarget.hasPointerCapture(sourceEvent.pointerId)) { return } rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function endSlide(sourceEvent, rect, ratio, rawValue) { rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); if (sourceEvent.currentTarget.hasPointerCapture(sourceEvent.pointerId)) { sourceEvent.currentTarget.releasePointerCapture(sourceEvent.pointerId) } $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function endSlide(sourceEvent, rect, ratio, rawValue) { rect = sourceEvent.currentTarget.getBoundingClientRect(); ratio = Math.max(0, Math.min(1, (sourceEvent.clientX - rect.left) / rect.width)); rawValue = Number(min) + ratio * (Number(max) - Number(min)); currentValue = Number(min) + Math.round((rawValue - Number(min)) / Number(step)) * Number(step); if (sourceEvent.currentTarget.hasPointerCapture(sourceEvent.pointerId)) { sourceEvent.currentTarget.releasePointerCapture(sourceEvent.pointerId) } output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function selectMark(sourceEvent, root, slider, input, output, nextValue, progressValue, detail) { if (readonly || disabled) { return } root = sourceEvent.currentTarget.closest(".wire-next--range-slider"); slider = root.querySelector(".wire-next__custom-slider"); input = root.querySelector(".wire-next__range-value"); output = root.querySelector("output"); nextValue = Number(sourceEvent.currentTarget.dataset.value); currentValue = nextValue; progressValue = (nextValue - Number(min)) / (Number(max) - Number(min)) * 100; slider.setAttribute("aria-valuenow", String(nextValue)); slider.style.setProperty("--wire-range-progress", progressValue + "%"); input.setAttribute("value", String(nextValue)); output.replaceChildren(String(nextValue)); detail = { value: nextValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
|
client function selectMark(sourceEvent, root, slider, input, outputElement, nextValue, progressValue, detail) { if (readonly || disabled) { return } root = sourceEvent.currentTarget.closest(".wire-next--range-slider"); slider = root.querySelector(".wire-next__custom-slider"); input = root.querySelector(".wire-next__range-value"); outputElement = root.querySelector("output"); nextValue = Number(sourceEvent.currentTarget.dataset.value); currentValue = nextValue; progressValue = (nextValue - Number(min)) / (Number(max) - Number(min)) * 100; slider.setAttribute("aria-valuenow", String(nextValue)); slider.style.setProperty("--wire-range-progress", progressValue + "%"); input.setAttribute("value", String(nextValue)); outputElement.replaceChildren(String(nextValue)); detail = { value: nextValue, min: min, max: max, step: step, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||||
function handleKey(sourceEvent) { if (sourceEvent.key === "ArrowRight") { sourceEvent.preventDefault(); currentValue = Math.min(Number(max), Number(currentValue) + Number(step)); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "ArrowLeft") { sourceEvent.preventDefault(); currentValue = Math.max(Number(min), Number(currentValue) - Number(step)); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "Home") { sourceEvent.preventDefault(); currentValue = Number(min); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "End") { sourceEvent.preventDefault(); currentValue = Number(max); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) } }
|
client function handleKey(sourceEvent) { if (sourceEvent.key === "ArrowRight") { sourceEvent.preventDefault(); currentValue = Math.min(Number(max), Number(currentValue) + Number(step)); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "ArrowLeft") { sourceEvent.preventDefault(); currentValue = Math.max(Number(min), Number(currentValue) - Number(step)); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "Home") { sourceEvent.preventDefault(); currentValue = Number(min); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) } if (sourceEvent.key === "End") { sourceEvent.preventDefault(); currentValue = Number(max); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) } }
|
||||||
function emitFocus(nameEvent, sourceEvent) { $emit(nameEvent, { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function emitFocus(nameEvent, sourceEvent) { output[nameEvent]({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function decreaseValue(sourceEvent) { currentValue = Math.max(Number(min), Number(currentValue) - Number(step)); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function decreaseValue(sourceEvent) { currentValue = Math.max(Number(min), Number(currentValue) - Number(step)); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function increaseValue(sourceEvent) { currentValue = Math.min(Number(max), Number(currentValue) + Number(step)); $emit("input", { value: currentValue, name: name, sourceEvent: sourceEvent }); $emit("change", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function increaseValue(sourceEvent) { currentValue = Math.min(Number(max), Number(currentValue) + Number(step)); output.input({ value: currentValue, name: name, sourceEvent: sourceEvent }); output.change({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--range-slider {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--range-slider {class}" data-variant="{variant}" data-inline="{inline}" data-invalid="{error ? 'true' : 'false'}">
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
component Rating {
|
component Rating {
|
||||||
|
outputs {
|
||||||
|
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
size = "default"
|
title: string = "Rating"
|
||||||
color = "primary"
|
description: string = ""
|
||||||
title = "Rating"
|
items: unknown[] = []
|
||||||
description = ""
|
variant: string = "default"
|
||||||
items = []
|
class: string = ""
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--rating wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--rating wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
component Scrollspy {
|
component Scrollspy {
|
||||||
|
outputs {
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event change = function
|
size: string = "default"
|
||||||
size = "default"
|
color: string = "primary"
|
||||||
color = "primary"
|
label: string = "Scrollspy"
|
||||||
label = "Scrollspy"
|
items: unknown[] = []
|
||||||
items = []
|
active: string = ""
|
||||||
active = ""
|
orientation: string = "horizontal"
|
||||||
orientation = "horizontal"
|
class: string = ""
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--scrollspy wire-next--{orientation} {class}" aria-label="{label}">
|
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--scrollspy wire-next--{orientation} {class}" aria-label="{label}">
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
component SearchBox {
|
component SearchBox {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
label = "Search Box"
|
label: string = "Search Box"
|
||||||
name = ""
|
name: string = ""
|
||||||
value = ""
|
value: string = ""
|
||||||
placeholder = ""
|
placeholder: string = ""
|
||||||
type = "search"
|
type: string = "search"
|
||||||
min = ""
|
min: string = ""
|
||||||
max = ""
|
max: string = ""
|
||||||
step = ""
|
step: string = ""
|
||||||
disabled = false
|
disabled: boolean = false
|
||||||
required = false
|
required: boolean = false
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
state query = value
|
state query = value
|
||||||
|
|||||||
@@ -1,36 +1,39 @@
|
|||||||
component Sidebar {
|
component Sidebar {
|
||||||
props {
|
outputs {
|
||||||
@event toggle = function
|
toggle(payload: { open: boolean })
|
||||||
@event open = function
|
open(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event close = function
|
close(payload: { source: string })
|
||||||
@event select = function
|
select(payload: { item: string | number | boolean | null | object; value: string | number | boolean; level: string })
|
||||||
size = "default"
|
|
||||||
color = "primary"
|
|
||||||
label = "Sidebar"
|
|
||||||
items = []
|
|
||||||
active = ""
|
|
||||||
orientation = "horizontal"
|
|
||||||
mobileLabel = "Open navigation"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state mobileOpen = false
|
props {
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
label: string = "Sidebar"
|
||||||
|
items: unknown[] = []
|
||||||
|
active: string = ""
|
||||||
|
orientation: string = "horizontal"
|
||||||
|
mobileLabel: string = "Open navigation"
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
state mobileOpen: boolean = false
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function toggleSidebar() {
|
client function toggleSidebar() {
|
||||||
mobileOpen = !mobileOpen
|
mobileOpen = !mobileOpen
|
||||||
$emit("toggle", { open: mobileOpen })
|
output.toggle({ open: mobileOpen })
|
||||||
$emit(mobileOpen ? "open" : "close", { source: "mobile" })
|
output[mobileOpen ? "open" : "close"]({ source: "mobile" })
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeSidebar() {
|
client function closeSidebar() {
|
||||||
mobileOpen = false
|
mobileOpen = false
|
||||||
$emit("close", { source: "mobile" })
|
output.close({ source: "mobile" })
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectItem(item, level) {
|
client function selectItem(item, level) {
|
||||||
mobileOpen = false
|
mobileOpen = false
|
||||||
$emit("select", { item: item, value: item.value || "", level: level })
|
output.select({ item: item, value: item.value || "", level: level })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
component Stepper {
|
component Stepper {
|
||||||
|
outputs {
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
previous(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
next(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
complete(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event change = function
|
size: string = "default"
|
||||||
@event previous = function
|
color: string = "primary"
|
||||||
@event next = function
|
label: string = "Stepper"
|
||||||
@event complete = function
|
items: unknown[] = []
|
||||||
size = "default"
|
active: string = ""
|
||||||
color = "primary"
|
orientation: string = "horizontal"
|
||||||
label = "Stepper"
|
class: string = ""
|
||||||
items = []
|
|
||||||
active = ""
|
|
||||||
orientation = "horizontal"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--stepper wire-next--{orientation} {class}" aria-label="{label}">
|
<nav class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--stepper wire-next--{orientation} {class}" aria-label="{label}">
|
||||||
|
|||||||
@@ -1,62 +1,65 @@
|
|||||||
component StrongPassword {
|
component StrongPassword {
|
||||||
props {
|
outputs {
|
||||||
size = "default"
|
input(payload: { value: string; score: number; maximumScore: number; percent: number; level: string })
|
||||||
color = "primary"
|
change(payload: { value: string; score: number; maximumScore: number; percent: number; level: string })
|
||||||
label = "Password"
|
strength(payload: { value: string; score: number; maximumScore: number; percent: number; level: string })
|
||||||
name = "password"
|
|
||||||
value = ""
|
|
||||||
placeholder = "Create a strong password"
|
|
||||||
autocomplete = "new-password"
|
|
||||||
minLength = 8
|
|
||||||
specialCharactersSet = "!@#$%^&*()_+-=[]{}|;:,.<>?"
|
|
||||||
requireLowercase = true
|
|
||||||
requireUppercase = true
|
|
||||||
requireNumber = true
|
|
||||||
requireSpecialCharacter = true
|
|
||||||
showRequirements = true
|
|
||||||
presentation = "inline"
|
|
||||||
hintText = "Use a unique password you do not use elsewhere."
|
|
||||||
emptyLabel = "Enter a password"
|
|
||||||
weakLabel = "Weak"
|
|
||||||
fairLabel = "Fair"
|
|
||||||
goodLabel = "Good"
|
|
||||||
strongLabel = "Strong"
|
|
||||||
disabled = false
|
|
||||||
readonly = false
|
|
||||||
required = false
|
|
||||||
invalid = false
|
|
||||||
validationMessage = ""
|
|
||||||
class = ""
|
|
||||||
@event input = function
|
|
||||||
@event change = function
|
|
||||||
@event strength = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
label: string = "Password"
|
||||||
|
name: string = "password"
|
||||||
|
value: string = ""
|
||||||
|
placeholder: string = "Create a strong password"
|
||||||
|
autocomplete: string = "new-password"
|
||||||
|
minLength: number = 8
|
||||||
|
specialCharactersSet: string = "!@#$%^&*()_+-=[]{}|;:,.<>?"
|
||||||
|
requireLowercase: boolean = true
|
||||||
|
requireUppercase: boolean = true
|
||||||
|
requireNumber: boolean = true
|
||||||
|
requireSpecialCharacter: boolean = true
|
||||||
|
showRequirements: boolean = true
|
||||||
|
presentation: string = "inline"
|
||||||
|
hintText: string = "Use a unique password you do not use elsewhere."
|
||||||
|
emptyLabel: string = "Enter a password"
|
||||||
|
weakLabel: string = "Weak"
|
||||||
|
fairLabel: string = "Fair"
|
||||||
|
goodLabel: string = "Good"
|
||||||
|
strongLabel: string = "Strong"
|
||||||
|
disabled: boolean = false
|
||||||
|
readonly: boolean = false
|
||||||
|
required: boolean = false
|
||||||
|
invalid: boolean = false
|
||||||
|
validationMessage: string = ""
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
state password = value
|
state password = value
|
||||||
state detailsOpen = false
|
state detailsOpen: boolean = false
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function hasMinimumLength() {
|
shared function hasMinimumLength() {
|
||||||
return password.length >= Number(minLength)
|
return password.length >= Number(minLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasLowercase() {
|
shared function hasLowercase() {
|
||||||
return password !== password.toUpperCase()
|
return password !== password.toUpperCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasUppercase() {
|
shared function hasUppercase() {
|
||||||
return password !== password.toLowerCase()
|
return password !== password.toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasNumber() {
|
shared function hasNumber() {
|
||||||
return containsCharacterAt("0123456789", 0)
|
return containsCharacterAt("0123456789", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasSpecialCharacter() {
|
shared function hasSpecialCharacter() {
|
||||||
return containsCharacterAt(specialCharactersSet, 0)
|
return containsCharacterAt(specialCharactersSet, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function containsCharacterAt(characters, index) {
|
shared function containsCharacterAt(characters, index) {
|
||||||
if (index >= characters.length) {
|
if (index >= characters.length) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -66,19 +69,19 @@ component StrongPassword {
|
|||||||
return containsCharacterAt(characters, index + 1)
|
return containsCharacterAt(characters, index + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function score() {
|
shared function score() {
|
||||||
return (hasMinimumLength() ? 1 : 0) + (requireLowercase && hasLowercase() ? 1 : 0) + (requireUppercase && hasUppercase() ? 1 : 0) + (requireNumber && hasNumber() ? 1 : 0) + (requireSpecialCharacter && hasSpecialCharacter() ? 1 : 0)
|
return (hasMinimumLength() ? 1 : 0) + (requireLowercase && hasLowercase() ? 1 : 0) + (requireUppercase && hasUppercase() ? 1 : 0) + (requireNumber && hasNumber() ? 1 : 0) + (requireSpecialCharacter && hasSpecialCharacter() ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function maximumScore() {
|
shared function maximumScore() {
|
||||||
return 1 + (requireLowercase ? 1 : 0) + (requireUppercase ? 1 : 0) + (requireNumber ? 1 : 0) + (requireSpecialCharacter ? 1 : 0)
|
return 1 + (requireLowercase ? 1 : 0) + (requireUppercase ? 1 : 0) + (requireNumber ? 1 : 0) + (requireSpecialCharacter ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function strengthPercent() {
|
shared function strengthPercent() {
|
||||||
return Math.round(score() / maximumScore() * 100)
|
return Math.round(score() / maximumScore() * 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
function strengthLevel() {
|
shared function strengthLevel() {
|
||||||
if (!password) {
|
if (!password) {
|
||||||
return "empty"
|
return "empty"
|
||||||
}
|
}
|
||||||
@@ -94,7 +97,7 @@ component StrongPassword {
|
|||||||
return "strong"
|
return "strong"
|
||||||
}
|
}
|
||||||
|
|
||||||
function strengthLabel() {
|
shared function strengthLabel() {
|
||||||
if (strengthLevel() === "weak") {
|
if (strengthLevel() === "weak") {
|
||||||
return weakLabel
|
return weakLabel
|
||||||
}
|
}
|
||||||
@@ -137,8 +140,8 @@ component StrongPassword {
|
|||||||
aria-describedby="{validationMessage ? name + '-validation' : hintText ? name + '-hint' : ''}"
|
aria-describedby="{validationMessage ? name + '-validation' : hintText ? name + '-hint' : ''}"
|
||||||
@focus="detailsOpen = true"
|
@focus="detailsOpen = true"
|
||||||
@blur="detailsOpen = false"
|
@blur="detailsOpen = false"
|
||||||
@input="password = event.target.value; $emit('input', { value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() }); $emit('strength', { value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
|
@input="password = event.target.value; output.input({ value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() }); output.strength({ value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
|
||||||
@change="$emit('change', { value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
|
@change="output.change({ value: password, score: score(), maximumScore: maximumScore(), percent: strengthPercent(), level: strengthLevel() })"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{#if presentation === "popover"}
|
{#if presentation === "popover"}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
component StyledIcon {
|
component StyledIcon {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
title = "Styled Icon"
|
title: string = "Styled Icon"
|
||||||
description = ""
|
description: string = ""
|
||||||
items = []
|
items: unknown[] = []
|
||||||
variant = "default"
|
variant: string = "default"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--styled-icon wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--styled-icon wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
component Tabs {
|
component Tabs {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
label = "Tabs"
|
label: string = "Tabs"
|
||||||
items = []
|
items: unknown[] = []
|
||||||
active = ""
|
active: string = ""
|
||||||
orientation = "horizontal"
|
orientation: string = "horizontal"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
state activeValue = active || (items[0] ? (items[0].value || items[0].id || "0") : "")
|
state activeValue = active || (items[0] ? (items[0].value || items[0].id || "0") : "")
|
||||||
|
|||||||
@@ -1,51 +1,54 @@
|
|||||||
component TimePicker {
|
component TimePicker {
|
||||||
|
outputs {
|
||||||
|
input(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
change(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
focus(payload: { value: string; name: string; sourceEvent: Event })
|
||||||
|
blur(payload: { value: string; name: string; sourceEvent: Event })
|
||||||
|
open(payload: { value: string; name: string; sourceEvent: Event })
|
||||||
|
close(payload: { value: string; name: string; sourceEvent: Event })
|
||||||
|
invalid(payload: { name: string; message: string; sourceEvent: Event })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event focus = function
|
id: string = ""
|
||||||
@event blur = function
|
name: string = ""
|
||||||
@event open = function
|
label: string = "Time"
|
||||||
@event close = function
|
hiddenLabel: boolean = false
|
||||||
@event invalid = function
|
value: string = ""
|
||||||
size = "default"
|
placeholder: string = ""
|
||||||
color = "primary"
|
variant: string = "normal"
|
||||||
id = ""
|
icon: string = "icon-[lucide--clock-3]"
|
||||||
name = ""
|
iconPosition: string = "end"
|
||||||
label = "Time"
|
helperText: string = ""
|
||||||
hiddenLabel = false
|
cornerHint: string = ""
|
||||||
value = ""
|
error: string = ""
|
||||||
placeholder = ""
|
inline: boolean = false
|
||||||
variant = "normal"
|
min: string = ""
|
||||||
icon = "icon-[lucide--clock-3]"
|
max: string = ""
|
||||||
iconPosition = "end"
|
step: string = ""
|
||||||
helperText = ""
|
format: string = "24"
|
||||||
cornerHint = ""
|
minuteStep: number = 5
|
||||||
error = ""
|
|
||||||
inline = false
|
|
||||||
min = ""
|
|
||||||
max = ""
|
|
||||||
step = ""
|
|
||||||
format = "24"
|
|
||||||
minuteStep = 5
|
|
||||||
hours = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]
|
hours = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"]
|
||||||
minutes = ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55"]
|
minutes = ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55"]
|
||||||
readonly = false
|
readonly: boolean = false
|
||||||
disabled = false
|
disabled: boolean = false
|
||||||
required = false
|
required: boolean = false
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
state currentValue = value
|
state currentValue = value
|
||||||
state selectedHour = value ? value.split(":")[0] : "00"
|
state selectedHour = value ? value.split(":")[0] : "00"
|
||||||
state selectedMinute = value ? value.split(":")[1] : "00"
|
state selectedMinute = value ? value.split(":")[1] : "00"
|
||||||
state expanded = false
|
state expanded: boolean = false
|
||||||
functions {
|
functions {
|
||||||
function commit(part, nextValue, sourceEvent, next, detail) { if (part === "hour") { selectedHour = String(nextValue).padStart(2, "0") } if (part === "minute") { selectedMinute = String(nextValue).padStart(2, "0") } next = selectedHour + ":" + selectedMinute; if ((min && next < min) || (max && next > max)) { return } currentValue = next; detail = { value: currentValue, hour: selectedHour, minute: selectedMinute, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
|
client function commit(part, nextValue, sourceEvent, next, detail) { if (part === "hour") { selectedHour = String(nextValue).padStart(2, "0") } if (part === "minute") { selectedMinute = String(nextValue).padStart(2, "0") } next = selectedHour + ":" + selectedMinute; if ((min && next < min) || (max && next > max)) { return } currentValue = next; detail = { value: currentValue, hour: selectedHour, minute: selectedMinute, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||||
function selectTimePart(sourceEvent, root, input, parts, hourValue, minuteValue, next, trigger, detail) { root = sourceEvent.currentTarget.closest(".wire-next--time-picker"); input = root.querySelector(".wire-next__time-value"); parts = String(input.value || value || "00:00").split(":"); hourValue = sourceEvent.currentTarget.dataset.part === "hour" ? sourceEvent.currentTarget.dataset.value : parts[0]; minuteValue = sourceEvent.currentTarget.dataset.part === "minute" ? sourceEvent.currentTarget.dataset.value : parts[1]; next = hourValue + ":" + minuteValue; if ((min && next < min) || (max && next > max)) { return } currentValue = next; input.setAttribute("value", next); trigger = root.querySelector(".wire-next__time-trigger span"); if (trigger) { trigger.replaceChildren(next) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: next, hour: hourValue, minute: minuteValue, name: name, sourceEvent: sourceEvent }; $emit("input", detail); $emit("change", detail) }
|
client function selectTimePart(sourceEvent, root, input, parts, hourValue, minuteValue, next, trigger, detail) { root = sourceEvent.currentTarget.closest(".wire-next--time-picker"); input = root.querySelector(".wire-next__time-value"); parts = String(input.value || value || "00:00").split(":"); hourValue = sourceEvent.currentTarget.dataset.part === "hour" ? sourceEvent.currentTarget.dataset.value : parts[0]; minuteValue = sourceEvent.currentTarget.dataset.part === "minute" ? sourceEvent.currentTarget.dataset.value : parts[1]; next = hourValue + ":" + minuteValue; if ((min && next < min) || (max && next > max)) { return } currentValue = next; input.setAttribute("value", next); trigger = root.querySelector(".wire-next__time-trigger span"); if (trigger) { trigger.replaceChildren(next) } sourceEvent.currentTarget.setAttribute("aria-pressed", "true"); detail = { value: next, hour: hourValue, minute: minuteValue, name: name, sourceEvent: sourceEvent }; output.input(detail); output.change(detail) }
|
||||||
function openPicker(sourceEvent) { expanded = true; $emit("open", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function openPicker(sourceEvent) { expanded = true; output.open({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function closePicker(sourceEvent) { expanded = false; $emit("close", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function closePicker(sourceEvent) { expanded = false; output.close({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function handleFocus(sourceEvent) { $emit("focus", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function handleFocus(sourceEvent) { output.focus({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function handleBlur(sourceEvent) { $emit("blur", { value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
client function handleBlur(sourceEvent) { output.blur({ value: currentValue, name: name, sourceEvent: sourceEvent }) }
|
||||||
function handleInvalid(sourceEvent) { $emit("invalid", { name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
|
client function handleInvalid(sourceEvent) { output.invalid({ name: name, message: sourceEvent.currentTarget.validationMessage, sourceEvent: sourceEvent }) }
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--time-picker {class}" data-variant="{variant}" data-inline="{inline}" data-floating="{variant === 'floating'}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
|
<div {...attrs} class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--time-picker {class}" data-variant="{variant}" data-inline="{inline}" data-floating="{variant === 'floating'}" data-invalid="{error ? 'true' : 'false'}" data-expanded="{expanded}">
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
component Timeline {
|
component Timeline {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
title = "Timeline"
|
title: string = "Timeline"
|
||||||
description = ""
|
description: string = ""
|
||||||
items = []
|
items: unknown[] = []
|
||||||
variant = "default"
|
variant: string = "default"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
component Toast {
|
component Toast {
|
||||||
|
outputs {
|
||||||
|
dismiss(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
action(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event dismiss = function
|
size: string = "default"
|
||||||
@event action = function
|
color: string = "primary"
|
||||||
size = "default"
|
title: string = "Toast"
|
||||||
color = "primary"
|
description: string = ""
|
||||||
title = "Toast"
|
items: unknown[] = []
|
||||||
description = ""
|
variant: string = "default"
|
||||||
items = []
|
class: string = ""
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--toast wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--toast wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
component ToastNotifications {
|
component ToastNotifications {
|
||||||
|
outputs {
|
||||||
|
add(payload: { sourceEvent?: Event; value: string | number | boolean | null | object; [key: string]: string | number | boolean | null | object } | string | number | boolean | null | object[])
|
||||||
|
dismiss(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
clear(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
action(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event add = function
|
size: string = "default"
|
||||||
@event dismiss = function
|
color: string = "primary"
|
||||||
@event clear = function
|
title: string = "Toast Notifications"
|
||||||
@event action = function
|
description: string = ""
|
||||||
size = "default"
|
items: unknown[] = []
|
||||||
color = "primary"
|
variant: string = "default"
|
||||||
title = "Toast Notifications"
|
class: string = ""
|
||||||
description = ""
|
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--toast-notifications wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--toast-notifications wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,48 +1,51 @@
|
|||||||
component ToggleCount {
|
component ToggleCount {
|
||||||
|
outputs {
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
toggle(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
variant = "segmented"
|
variant: string = "segmented"
|
||||||
class = ""
|
class: string = ""
|
||||||
|
|
||||||
name = "billing-cycle"
|
name: string = "billing-cycle"
|
||||||
value = "monthly"
|
value: string = "monthly"
|
||||||
firstValue = "monthly"
|
firstValue: string = "monthly"
|
||||||
firstLabel = "Monthly"
|
firstLabel: string = "Monthly"
|
||||||
secondValue = "annual"
|
secondValue: string = "annual"
|
||||||
secondLabel = "Annual"
|
secondLabel: string = "Annual"
|
||||||
ariaLabel = "Billing frequency"
|
ariaLabel: string = "Billing frequency"
|
||||||
|
|
||||||
items = []
|
items: unknown[] = []
|
||||||
currency = "$"
|
currency: string = "$"
|
||||||
suffix = ""
|
suffix: string = ""
|
||||||
firstValueKey = "monthly"
|
firstValueKey: string = "monthly"
|
||||||
secondValueKey = "annual"
|
secondValueKey: string = "annual"
|
||||||
emptyValue = "—"
|
emptyValue: string = "—"
|
||||||
|
|
||||||
align = "end"
|
align: string = "end"
|
||||||
fullWidth = true
|
fullWidth: boolean = true
|
||||||
disabled = false
|
disabled: boolean = false
|
||||||
animate = true
|
animate: boolean = true
|
||||||
animationDuration = 450
|
animationDuration: number = 450
|
||||||
animationSteps = 18
|
animationSteps: number = 18
|
||||||
|
|
||||||
@event change = function
|
|
||||||
@event toggle = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state selectedValue = value
|
state selectedValue = value
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function isFirstSelected() {
|
shared function isFirstSelected() {
|
||||||
return selectedValue === firstValue
|
return selectedValue === firstValue
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSecondSelected() {
|
shared function isSecondSelected() {
|
||||||
return selectedValue === secondValue
|
return selectedValue === secondValue
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayValue(item) {
|
shared function displayValue(item) {
|
||||||
if (isSecondSelected()) {
|
if (isSecondSelected()) {
|
||||||
return item[secondValueKey] !== undefined
|
return item[secondValueKey] !== undefined
|
||||||
? item[secondValueKey]
|
? item[secondValueKey]
|
||||||
@@ -54,7 +57,7 @@ component ToggleCount {
|
|||||||
: emptyValue
|
: emptyValue
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispatchToggleEvent(sourceEvent, previousValue, root, customEvent) {
|
client function dispatchToggleEvent(sourceEvent, previousValue, root, customEvent) {
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-toggle-count]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-toggle-count]")
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
@@ -84,7 +87,7 @@ component ToggleCount {
|
|||||||
root.dispatchEvent(customEvent)
|
root.dispatchEvent(customEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectValue(sourceEvent, nextValue, previousValue) {
|
client function selectValue(sourceEvent, nextValue, previousValue) {
|
||||||
if (disabled || selectedValue === nextValue) {
|
if (disabled || selectedValue === nextValue) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -102,18 +105,29 @@ component ToggleCount {
|
|||||||
dispatchToggleEvent(sourceEvent, previousValue)
|
dispatchToggleEvent(sourceEvent, previousValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
function animateDisplayedValues(sourceEvent, previousValue, root, nodes) {
|
client function animateDisplayedValues(sourceEvent, previousValue, root, nodes, animationToken) {
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-toggle-count]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-toggle-count]")
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
animationToken = String(Date.now()) + ":" + String(selectedValue)
|
||||||
|
root.setAttribute("data-animation-token", animationToken)
|
||||||
nodes = root.querySelectorAll("[data-toggle-count-value]")
|
nodes = root.querySelectorAll("[data-toggle-count-value]")
|
||||||
animateValueAt(nodes, 0, previousValue)
|
animateValueAt(nodes, 0, previousValue, root, animationToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
function animateValueAt(nodes, index, previousValue, node, fromValue, toValue) {
|
client function animateValueAt(
|
||||||
|
nodes,
|
||||||
|
index,
|
||||||
|
previousValue,
|
||||||
|
root,
|
||||||
|
animationToken,
|
||||||
|
node,
|
||||||
|
fromValue,
|
||||||
|
toValue
|
||||||
|
) {
|
||||||
if (index >= nodes.length) {
|
if (index >= nodes.length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -131,17 +145,40 @@ component ToggleCount {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (!Number.isNaN(fromValue) && !Number.isNaN(toValue)) {
|
if (!Number.isNaN(fromValue) && !Number.isNaN(toValue)) {
|
||||||
animateValueFrame(node, fromValue, toValue, 0)
|
node.replaceChildren(String(fromValue))
|
||||||
|
scheduleValueFrame(
|
||||||
|
node,
|
||||||
|
fromValue,
|
||||||
|
toValue,
|
||||||
|
1,
|
||||||
|
Math.max(1, Number(animationSteps) || 1),
|
||||||
|
Math.max(1, Number(animationDuration) || 1),
|
||||||
|
root,
|
||||||
|
animationToken
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
animateValueAt(nodes, index + 1, previousValue)
|
animateValueAt(
|
||||||
|
nodes,
|
||||||
|
index + 1,
|
||||||
|
previousValue,
|
||||||
|
root,
|
||||||
|
animationToken
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function animateValueFrame(node, fromValue, toValue, frame, totalFrames, nextValue) {
|
client function scheduleValueFrame(
|
||||||
totalFrames = Math.max(1, Number(animationSteps) || 1)
|
node,
|
||||||
|
fromValue,
|
||||||
if (frame >= totalFrames) {
|
toValue,
|
||||||
node.replaceChildren(String(toValue))
|
frame,
|
||||||
|
totalFrames,
|
||||||
|
duration,
|
||||||
|
root,
|
||||||
|
animationToken,
|
||||||
|
nextValue
|
||||||
|
) {
|
||||||
|
if (frame > totalFrames) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,19 +186,45 @@ component ToggleCount {
|
|||||||
fromValue +
|
fromValue +
|
||||||
(toValue - fromValue) * (frame / totalFrames)
|
(toValue - fromValue) * (frame / totalFrames)
|
||||||
)
|
)
|
||||||
node.replaceChildren(String(nextValue))
|
|
||||||
|
|
||||||
setTimeout(
|
setTimeout(
|
||||||
animateValueFrame,
|
applyAnimatedValue,
|
||||||
Math.max(1, Number(animationDuration) / totalFrames),
|
Math.max(1, duration * frame / totalFrames),
|
||||||
|
node,
|
||||||
|
nextValue,
|
||||||
|
root,
|
||||||
|
animationToken
|
||||||
|
)
|
||||||
|
|
||||||
|
scheduleValueFrame(
|
||||||
node,
|
node,
|
||||||
fromValue,
|
fromValue,
|
||||||
toValue,
|
toValue,
|
||||||
frame + 1
|
frame + 1,
|
||||||
|
totalFrames,
|
||||||
|
duration,
|
||||||
|
root,
|
||||||
|
animationToken
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleValue(sourceEvent) {
|
client function applyAnimatedValue(
|
||||||
|
node,
|
||||||
|
nextValue,
|
||||||
|
root,
|
||||||
|
animationToken
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
root &&
|
||||||
|
root.getAttribute("data-animation-token") !== animationToken
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
node.replaceChildren(String(nextValue))
|
||||||
|
}
|
||||||
|
|
||||||
|
client function toggleValue(sourceEvent) {
|
||||||
selectValue(
|
selectValue(
|
||||||
sourceEvent,
|
sourceEvent,
|
||||||
isFirstSelected() ? secondValue : firstValue
|
isFirstSelected() ? secondValue : firstValue
|
||||||
|
|||||||
@@ -1,49 +1,52 @@
|
|||||||
component TogglePassword {
|
component TogglePassword {
|
||||||
props {
|
outputs {
|
||||||
size = "default"
|
input(payload: { name?: string; value: string | number | boolean | null | object; visible: boolean })
|
||||||
color = "primary"
|
change(payload: { name?: string; value: string | number | boolean | null | object; visible: boolean })
|
||||||
label = "Password"
|
toggle(payload: { visible: boolean })
|
||||||
name = "password"
|
|
||||||
value = ""
|
|
||||||
placeholder = "Enter your password"
|
|
||||||
autocomplete = "current-password"
|
|
||||||
minlength = ""
|
|
||||||
maxlength = ""
|
|
||||||
pattern = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}"
|
|
||||||
fields = []
|
|
||||||
visible = false
|
|
||||||
toggleable = true
|
|
||||||
toggleMode = "button"
|
|
||||||
checkboxLabel = "Show password"
|
|
||||||
showLabel = "Show password"
|
|
||||||
hideLabel = "Hide password"
|
|
||||||
disabled = false
|
|
||||||
readonly = false
|
|
||||||
required = false
|
|
||||||
invalid = false
|
|
||||||
helpText = ""
|
|
||||||
validationMessage = ""
|
|
||||||
class = ""
|
|
||||||
@event input = function
|
|
||||||
@event change = function
|
|
||||||
@event toggle = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props {
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "primary"
|
||||||
|
label: string = "Password"
|
||||||
|
name: string = "password"
|
||||||
|
value: string = ""
|
||||||
|
placeholder: string = "Enter your password"
|
||||||
|
autocomplete: string = "current-password"
|
||||||
|
minlength: string = ""
|
||||||
|
maxlength: string = ""
|
||||||
|
pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}"
|
||||||
|
fields: unknown[] = []
|
||||||
|
visible: boolean = false
|
||||||
|
toggleable: boolean = true
|
||||||
|
toggleMode: string = "button"
|
||||||
|
checkboxLabel: string = "Show password"
|
||||||
|
showLabel: string = "Show password"
|
||||||
|
hideLabel: string = "Hide password"
|
||||||
|
disabled: boolean = false
|
||||||
|
readonly: boolean = false
|
||||||
|
required: boolean = false
|
||||||
|
invalid: boolean = false
|
||||||
|
helpText: string = ""
|
||||||
|
validationMessage: string = ""
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
state revealed = visible
|
state revealed = visible
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function toggleVisibility() {
|
shared function toggleVisibility() {
|
||||||
if (disabled || readonly || !toggleable) {
|
if (disabled || readonly || !toggleable) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
revealed = !revealed
|
revealed = !revealed
|
||||||
}
|
}
|
||||||
|
|
||||||
function fieldId(field, index) {
|
shared function fieldId(field, index) {
|
||||||
return field.id || field.name || name + "-" + index
|
return field.id || field.name || name + "-" + index
|
||||||
}
|
}
|
||||||
|
|
||||||
function fieldName(field, index) {
|
shared function fieldName(field, index) {
|
||||||
return field.name || name + "-" + index
|
return field.name || name + "-" + index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,8 +77,8 @@ component TogglePassword {
|
|||||||
readonly="{readonly || field.readonly}"
|
readonly="{readonly || field.readonly}"
|
||||||
required="{required || field.required}"
|
required="{required || field.required}"
|
||||||
aria-invalid="{invalid ? 'true' : 'false'}"
|
aria-invalid="{invalid ? 'true' : 'false'}"
|
||||||
@input="$emit('input', { name: event.target.name, value: event.target.value, visible: revealed })"
|
@input="output.input({ name: event.target.name, value: event.target.value, visible: revealed })"
|
||||||
@change="$emit('change', { name: event.target.name, value: event.target.value, visible: revealed })"
|
@change="output.change({ name: event.target.name, value: event.target.value, visible: revealed })"
|
||||||
/>
|
/>
|
||||||
{#if toggleable && toggleMode === "button"}
|
{#if toggleable && toggleMode === "button"}
|
||||||
<button
|
<button
|
||||||
@@ -85,7 +88,7 @@ component TogglePassword {
|
|||||||
title="{revealed ? hideLabel : showLabel}"
|
title="{revealed ? hideLabel : showLabel}"
|
||||||
aria-pressed="{revealed ? 'true' : 'false'}"
|
aria-pressed="{revealed ? 'true' : 'false'}"
|
||||||
disabled="{disabled || readonly}"
|
disabled="{disabled || readonly}"
|
||||||
@click="toggleVisibility(); $emit('toggle', { visible: revealed })"
|
@click="toggleVisibility(); output.toggle({ visible: revealed })"
|
||||||
>
|
>
|
||||||
<span class="wire-next__password-icon wire-next__password-icon--show" aria-hidden="true"></span>
|
<span class="wire-next__password-icon wire-next__password-icon--show" aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
@@ -113,8 +116,8 @@ component TogglePassword {
|
|||||||
required="{required}"
|
required="{required}"
|
||||||
aria-invalid="{invalid ? 'true' : 'false'}"
|
aria-invalid="{invalid ? 'true' : 'false'}"
|
||||||
aria-describedby="{validationMessage ? name + '-validation' : helpText ? name + '-help' : ''}"
|
aria-describedby="{validationMessage ? name + '-validation' : helpText ? name + '-help' : ''}"
|
||||||
@input="$emit('input', { value: event.target.value, visible: revealed })"
|
@input="output.input({ value: event.target.value, visible: revealed })"
|
||||||
@change="$emit('change', { value: event.target.value, visible: revealed })"
|
@change="output.change({ value: event.target.value, visible: revealed })"
|
||||||
/>
|
/>
|
||||||
{#if toggleable && toggleMode === "button"}
|
{#if toggleable && toggleMode === "button"}
|
||||||
<button
|
<button
|
||||||
@@ -124,7 +127,7 @@ component TogglePassword {
|
|||||||
title="{revealed ? hideLabel : showLabel}"
|
title="{revealed ? hideLabel : showLabel}"
|
||||||
aria-pressed="{revealed ? 'true' : 'false'}"
|
aria-pressed="{revealed ? 'true' : 'false'}"
|
||||||
disabled="{disabled || readonly}"
|
disabled="{disabled || readonly}"
|
||||||
@click="toggleVisibility(); $emit('toggle', { visible: revealed })"
|
@click="toggleVisibility(); output.toggle({ visible: revealed })"
|
||||||
>
|
>
|
||||||
<span class="wire-next__password-icon wire-next__password-icon--show" aria-hidden="true"></span>
|
<span class="wire-next__password-icon wire-next__password-icon--show" aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
@@ -137,7 +140,7 @@ component TogglePassword {
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked="{revealed}"
|
checked="{revealed}"
|
||||||
disabled="{disabled || readonly}"
|
disabled="{disabled || readonly}"
|
||||||
@change="revealed = event.target.checked; $emit('toggle', { visible: revealed })"
|
@change="revealed = event.target.checked; output.toggle({ visible: revealed })"
|
||||||
/>
|
/>
|
||||||
<span>{checkboxLabel}</span>
|
<span>{checkboxLabel}</span>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
component TreeView {
|
component TreeView {
|
||||||
|
outputs {
|
||||||
|
select(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
toggle(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
expand(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
collapse(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event select = function
|
size: string = "default"
|
||||||
@event toggle = function
|
color: string = "primary"
|
||||||
@event expand = function
|
title: string = "Tree View"
|
||||||
@event collapse = function
|
description: string = ""
|
||||||
size = "default"
|
items: unknown[] = []
|
||||||
color = "primary"
|
variant: string = "default"
|
||||||
title = "Tree View"
|
class: string = ""
|
||||||
description = ""
|
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--tree-view wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--tree-view wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
component Typography {
|
component Typography {
|
||||||
props {
|
props {
|
||||||
size = "default"
|
size: string = "default"
|
||||||
color = "primary"
|
color: string = "primary"
|
||||||
columns = 2
|
columns: number = 2
|
||||||
gap = "md"
|
gap: string = "md"
|
||||||
maxWidth = "xl"
|
maxWidth: string = "xl"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
component WysiwygEditor {
|
component WysiwygEditor {
|
||||||
|
outputs {
|
||||||
|
input(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
change(payload: { value?: string | number | boolean | null; values?: Array<string | number | boolean | null | object>; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null)
|
||||||
|
focus(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
blur(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event input = function
|
size: string = "default"
|
||||||
@event change = function
|
color: string = "primary"
|
||||||
@event focus = function
|
title: string = "Wysiwyg Editor"
|
||||||
@event blur = function
|
description: string = ""
|
||||||
size = "default"
|
items: unknown[] = []
|
||||||
color = "primary"
|
variant: string = "default"
|
||||||
title = "Wysiwyg Editor"
|
class: string = ""
|
||||||
description = ""
|
|
||||||
items = []
|
|
||||||
variant = "default"
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
view {
|
view {
|
||||||
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--wysiwyg-editor wire-next--variant-{variant} {class}">
|
<section class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--wysiwyg-editor wire-next--variant-{variant} {class}">
|
||||||
|
|||||||
@@ -1,38 +1,41 @@
|
|||||||
component Alert {
|
component Alert {
|
||||||
props {
|
outputs {
|
||||||
size = "default"
|
dismiss(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
color = "info"
|
action(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
variant = "soft"
|
|
||||||
class = ""
|
|
||||||
radius = "md"
|
|
||||||
shadow = "sm"
|
|
||||||
|
|
||||||
title = "Alert"
|
|
||||||
description = ""
|
|
||||||
items = []
|
|
||||||
actions = []
|
|
||||||
|
|
||||||
showIcon = false
|
|
||||||
icon = ""
|
|
||||||
dismissible = false
|
|
||||||
dismissLabel = "Dismiss alert"
|
|
||||||
role = "alert"
|
|
||||||
live = "polite"
|
|
||||||
|
|
||||||
linkLabel = ""
|
|
||||||
linkHref = ""
|
|
||||||
actionLabel = ""
|
|
||||||
actionHref = ""
|
|
||||||
compact = false
|
|
||||||
|
|
||||||
@event dismiss = function
|
|
||||||
@event action = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state visible = true
|
props {
|
||||||
|
size: string = "default"
|
||||||
|
color: string = "info"
|
||||||
|
variant: string = "soft"
|
||||||
|
class: string = ""
|
||||||
|
radius: string = "md"
|
||||||
|
shadow: string = "sm"
|
||||||
|
|
||||||
|
title: string = "Alert"
|
||||||
|
description: string = ""
|
||||||
|
items: unknown[] = []
|
||||||
|
actions: unknown[] = []
|
||||||
|
|
||||||
|
showIcon: boolean = false
|
||||||
|
icon: string = ""
|
||||||
|
dismissible: boolean = false
|
||||||
|
dismissLabel: string = "Dismiss alert"
|
||||||
|
role: string = "alert"
|
||||||
|
live: string = "polite"
|
||||||
|
|
||||||
|
linkLabel: string = ""
|
||||||
|
linkHref: string = ""
|
||||||
|
actionLabel: string = ""
|
||||||
|
actionHref: string = ""
|
||||||
|
compact: boolean = false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
state visible: boolean = true
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function dispatchAlertEvent(sourceEvent, eventName, action, root, customEvent) {
|
client function dispatchAlertEvent(sourceEvent, eventName, action, root, customEvent) {
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-alert]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-alert]")
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
@@ -50,12 +53,12 @@ component Alert {
|
|||||||
root.dispatchEvent(customEvent)
|
root.dispatchEvent(customEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function dismissAlert(sourceEvent) {
|
client function dismissAlert(sourceEvent) {
|
||||||
visible = false
|
visible = false
|
||||||
dispatchAlertEvent(sourceEvent, "dismiss", null)
|
dispatchAlertEvent(sourceEvent, "dismiss", null)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectAction(sourceEvent, action) {
|
client function selectAction(sourceEvent, action) {
|
||||||
dispatchAlertEvent(sourceEvent, "action", action)
|
dispatchAlertEvent(sourceEvent, "action", action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,32 @@
|
|||||||
component Avatar {
|
component Avatar {
|
||||||
|
outputs {
|
||||||
|
load(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string)
|
||||||
|
click(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event load = function
|
src: string = ""
|
||||||
@event error = function
|
alt: string = ""
|
||||||
@event click = function
|
initials: string = ""
|
||||||
src = ""
|
size: string = "md"
|
||||||
alt = ""
|
color: string = "primary"
|
||||||
initials = ""
|
variant: string = "solid"
|
||||||
size = "md"
|
shape: string = "circle"
|
||||||
color = "primary"
|
|
||||||
variant = "solid"
|
|
||||||
shape = "circle"
|
|
||||||
|
|
||||||
status = ""
|
status: string = ""
|
||||||
statusLabel = ""
|
statusLabel: string = ""
|
||||||
statusPosition = "bottom"
|
statusPosition: string = "bottom"
|
||||||
|
|
||||||
badge = ""
|
badge: string = ""
|
||||||
badgeIcon = ""
|
badgeIcon: string = ""
|
||||||
badgeLabel = ""
|
badgeLabel: string = ""
|
||||||
|
|
||||||
tooltip = ""
|
tooltip: string = ""
|
||||||
name = ""
|
name: string = ""
|
||||||
description = ""
|
description: string = ""
|
||||||
loading = "lazy"
|
loading: string = "lazy"
|
||||||
class = ""
|
class: string = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,38 +1,41 @@
|
|||||||
component Badge {
|
component Badge {
|
||||||
props {
|
outputs {
|
||||||
label = "Badge"
|
dismiss(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
size = "md"
|
|
||||||
color = "primary"
|
|
||||||
variant = "solid"
|
|
||||||
shape = "pill"
|
|
||||||
class = ""
|
|
||||||
|
|
||||||
icon = ""
|
|
||||||
iconPosition = "start"
|
|
||||||
dot = false
|
|
||||||
dotOnly = false
|
|
||||||
dotLabel = "Status"
|
|
||||||
animated = false
|
|
||||||
|
|
||||||
avatarSrc = ""
|
|
||||||
avatarAlt = ""
|
|
||||||
dismissible = false
|
|
||||||
dismissLabel = "Remove badge"
|
|
||||||
truncate = false
|
|
||||||
maxWidth = "12rem"
|
|
||||||
|
|
||||||
anchorLabel = ""
|
|
||||||
anchorIcon = ""
|
|
||||||
placement = "inline"
|
|
||||||
anchorLabelText = "Badge anchor"
|
|
||||||
|
|
||||||
@event dismiss = function
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state visible = true
|
props {
|
||||||
|
label: string = "Badge"
|
||||||
|
size: string = "md"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "solid"
|
||||||
|
shape: string = "pill"
|
||||||
|
class: string = ""
|
||||||
|
|
||||||
|
icon: string = ""
|
||||||
|
iconPosition: string = "start"
|
||||||
|
dot: boolean = false
|
||||||
|
dotOnly: boolean = false
|
||||||
|
dotLabel: string = "Status"
|
||||||
|
animated: boolean = false
|
||||||
|
|
||||||
|
avatarSrc: string = ""
|
||||||
|
avatarAlt: string = ""
|
||||||
|
dismissible: boolean = false
|
||||||
|
dismissLabel: string = "Remove badge"
|
||||||
|
truncate: boolean = false
|
||||||
|
maxWidth: string = "12rem"
|
||||||
|
|
||||||
|
anchorLabel: string = ""
|
||||||
|
anchorIcon: string = ""
|
||||||
|
placement: string = "inline"
|
||||||
|
anchorLabelText: string = "Badge anchor"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
state visible: boolean = true
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function dismissBadge(sourceEvent, root, customEvent) {
|
client function dismissBadge(sourceEvent, root, customEvent) {
|
||||||
visible = false
|
visible = false
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-badge]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-badge]")
|
||||||
customEvent = document.createEvent("CustomEvent")
|
customEvent = document.createEvent("CustomEvent")
|
||||||
|
|||||||
@@ -1,33 +1,36 @@
|
|||||||
component Button {
|
component Button {
|
||||||
|
outputs {
|
||||||
|
click(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
focus(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
blur(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
|
}
|
||||||
|
|
||||||
props {
|
props {
|
||||||
@event click = function
|
label: string = "Button"
|
||||||
@event focus = function
|
loadingLabel: string = "Loading…"
|
||||||
@event blur = function
|
description: string = ""
|
||||||
label = "Button"
|
as: string = ""
|
||||||
loadingLabel = "Loading…"
|
href: string = ""
|
||||||
description = ""
|
target: string = ""
|
||||||
as = ""
|
rel: string = ""
|
||||||
href = ""
|
type: string = "button"
|
||||||
target = ""
|
variant: string = "default"
|
||||||
rel = ""
|
color: string = "primary"
|
||||||
type = "button"
|
size: string = "default"
|
||||||
variant = "default"
|
disabled: boolean = false
|
||||||
color = "primary"
|
loading: boolean = false
|
||||||
size = "default"
|
pill: boolean = false
|
||||||
disabled = false
|
fullWidth: boolean = false
|
||||||
loading = false
|
icon: string = ""
|
||||||
pill = false
|
iconPosition: string = "start"
|
||||||
fullWidth = false
|
ariaLabel: string = ""
|
||||||
icon = ""
|
ariaPressed: string = ""
|
||||||
iconPosition = "start"
|
ariaExpanded: string = ""
|
||||||
ariaLabel = ""
|
ariaControls: string = ""
|
||||||
ariaPressed = ""
|
title: string = ""
|
||||||
ariaExpanded = ""
|
autofocus: boolean = false
|
||||||
ariaControls = ""
|
controlClass: string = ""
|
||||||
title = ""
|
class: string = ""
|
||||||
autofocus = false
|
|
||||||
controlClass = ""
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
view {
|
view {
|
||||||
|
|||||||
@@ -1,48 +1,51 @@
|
|||||||
component Card {
|
component Card {
|
||||||
props {
|
outputs {
|
||||||
@event click = function
|
click(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event action = function
|
action(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event navigate = function
|
navigate(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event dismiss = function
|
dismiss(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event load = function
|
load(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object })
|
||||||
@event error = function
|
error(payload: { error: Error | string; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | Error | string)
|
||||||
title = "Card title"
|
|
||||||
subtitle = ""
|
|
||||||
description = ""
|
|
||||||
header = ""
|
|
||||||
footer = ""
|
|
||||||
imageSrc = ""
|
|
||||||
imageAlt = ""
|
|
||||||
imagePosition = "top"
|
|
||||||
actionLabel = ""
|
|
||||||
actionHref = ""
|
|
||||||
headerActions = []
|
|
||||||
navigation = []
|
|
||||||
activeNav = ""
|
|
||||||
mobileNavigation = false
|
|
||||||
alertTitle = ""
|
|
||||||
alertDescription = ""
|
|
||||||
empty = false
|
|
||||||
emptyTitle = "No data to show"
|
|
||||||
emptyIcon = "icon-[lucide--inbox]"
|
|
||||||
items = []
|
|
||||||
size = "md"
|
|
||||||
color = "primary"
|
|
||||||
variant = "default"
|
|
||||||
layout = "vertical"
|
|
||||||
align = "left"
|
|
||||||
hover = "none"
|
|
||||||
scrollable = false
|
|
||||||
maxHeight = "18rem"
|
|
||||||
dismissible = false
|
|
||||||
ariaLabel = ""
|
|
||||||
class = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state dismissed = false
|
props {
|
||||||
|
title: string = "Card title"
|
||||||
|
subtitle: string = ""
|
||||||
|
description: string = ""
|
||||||
|
header: string = ""
|
||||||
|
footer: string = ""
|
||||||
|
imageSrc: string = ""
|
||||||
|
imageAlt: string = ""
|
||||||
|
imagePosition: string = "top"
|
||||||
|
actionLabel: string = ""
|
||||||
|
actionHref: string = ""
|
||||||
|
headerActions: unknown[] = []
|
||||||
|
navigation: unknown[] = []
|
||||||
|
activeNav: string = ""
|
||||||
|
mobileNavigation: boolean = false
|
||||||
|
alertTitle: string = ""
|
||||||
|
alertDescription: string = ""
|
||||||
|
empty: boolean = false
|
||||||
|
emptyTitle: string = "No data to show"
|
||||||
|
emptyIcon: string = "icon-[lucide--inbox]"
|
||||||
|
items: unknown[] = []
|
||||||
|
size: string = "md"
|
||||||
|
color: string = "primary"
|
||||||
|
variant: string = "default"
|
||||||
|
layout: string = "vertical"
|
||||||
|
align: string = "left"
|
||||||
|
hover: string = "none"
|
||||||
|
scrollable: boolean = false
|
||||||
|
maxHeight: string = "18rem"
|
||||||
|
dismissible: boolean = false
|
||||||
|
ariaLabel: string = ""
|
||||||
|
class: string = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
state dismissed: boolean = false
|
||||||
|
|
||||||
functions {
|
functions {
|
||||||
function dispatchCardNavigation(sourceEvent, item, index, root, customEvent) {
|
client function dispatchCardNavigation(sourceEvent, item, index, root, customEvent) {
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-card]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-card]")
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
@@ -58,7 +61,7 @@ component Card {
|
|||||||
root.dispatchEvent(customEvent)
|
root.dispatchEvent(customEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispatchCardNavigationValue(sourceEvent, root, customEvent) {
|
client function dispatchCardNavigationValue(sourceEvent, root, customEvent) {
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-card]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-card]")
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
@@ -73,7 +76,7 @@ component Card {
|
|||||||
root.dispatchEvent(customEvent)
|
root.dispatchEvent(customEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispatchCardHeaderAction(sourceEvent, action, index, root, customEvent) {
|
client function dispatchCardHeaderAction(sourceEvent, action, index, root, customEvent) {
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-card]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-card]")
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
@@ -89,7 +92,7 @@ component Card {
|
|||||||
root.dispatchEvent(customEvent)
|
root.dispatchEvent(customEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function dismissCard(sourceEvent, root, customEvent) {
|
client function dismissCard(sourceEvent, root, customEvent) {
|
||||||
dismissed = true
|
dismissed = true
|
||||||
root = sourceEvent.currentTarget.closest("[data-wrn-card]")
|
root = sourceEvent.currentTarget.closest("[data-wrn-card]")
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user