@vielzeug/refine 1.3.1 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/checkbox-group.cjs +7 -7
- package/dist/checkbox-group.cjs.map +1 -1
- package/dist/checkbox-group.js +35 -26
- package/dist/checkbox-group.js.map +1 -1
- package/dist/checkbox.cjs +3 -3
- package/dist/checkbox.cjs.map +1 -1
- package/dist/checkbox.js +24 -19
- package/dist/checkbox.js.map +1 -1
- package/dist/combobox.cjs +24 -24
- package/dist/combobox.cjs.map +1 -1
- package/dist/combobox.js +133 -129
- package/dist/combobox.js.map +1 -1
- package/dist/custom-elements.json +5473 -4925
- package/dist/headless/auto-resize.cjs +2 -0
- package/dist/headless/auto-resize.cjs.map +1 -0
- package/dist/headless/auto-resize.d.ts +29 -0
- package/dist/headless/auto-resize.d.ts.map +1 -0
- package/dist/headless/auto-resize.js +16 -0
- package/dist/headless/auto-resize.js.map +1 -0
- package/dist/headless/checkable.cjs +1 -1
- package/dist/headless/checkable.cjs.map +1 -1
- package/dist/headless/checkable.d.ts +25 -7
- package/dist/headless/checkable.d.ts.map +1 -1
- package/dist/headless/checkable.js +19 -14
- package/dist/headless/checkable.js.map +1 -1
- package/dist/headless/choice-field.cjs +1 -1
- package/dist/headless/choice-field.cjs.map +1 -1
- package/dist/headless/choice-field.d.ts +21 -0
- package/dist/headless/choice-field.d.ts.map +1 -1
- package/dist/headless/choice-field.js +27 -19
- package/dist/headless/choice-field.js.map +1 -1
- package/dist/headless/composer.cjs +2 -0
- package/dist/headless/composer.cjs.map +1 -0
- package/dist/headless/composer.d.ts +44 -0
- package/dist/headless/composer.d.ts.map +1 -0
- package/dist/headless/composer.js +21 -0
- package/dist/headless/composer.js.map +1 -0
- package/dist/headless/field-base.cjs +1 -1
- package/dist/headless/field-base.cjs.map +1 -1
- package/dist/headless/field-base.d.ts +97 -84
- package/dist/headless/field-base.d.ts.map +1 -1
- package/dist/headless/field-base.js +43 -32
- package/dist/headless/field-base.js.map +1 -1
- package/dist/headless/index.d.ts +3 -1
- package/dist/headless/index.d.ts.map +1 -1
- package/dist/headless/text-field.cjs +1 -1
- package/dist/headless/text-field.cjs.map +1 -1
- package/dist/headless/text-field.d.ts +40 -0
- package/dist/headless/text-field.d.ts.map +1 -1
- package/dist/headless/text-field.js +30 -25
- package/dist/headless/text-field.js.map +1 -1
- package/dist/headless.cjs +1 -1
- package/dist/headless.js +27 -25
- package/dist/index.cjs +1 -1
- package/dist/index.js +61 -60
- package/dist/input.cjs +9 -9
- package/dist/input.cjs.map +1 -1
- package/dist/input.js +49 -44
- package/dist/input.js.map +1 -1
- package/dist/inputs/checkbox/checkbox.d.ts +3 -0
- package/dist/inputs/checkbox/checkbox.d.ts.map +1 -1
- package/dist/inputs/combobox/combobox.d.ts +1 -0
- package/dist/inputs/combobox/combobox.d.ts.map +1 -1
- package/dist/inputs/combobox/combobox.types.d.ts +2 -0
- package/dist/inputs/combobox/combobox.types.d.ts.map +1 -1
- package/dist/inputs/index.d.ts +2 -0
- package/dist/inputs/index.d.ts.map +1 -1
- package/dist/inputs/input/input.d.ts.map +1 -1
- package/dist/inputs/message-composer/message-composer.css.cjs +2 -0
- package/dist/inputs/message-composer/message-composer.css.cjs.map +1 -0
- package/dist/inputs/message-composer/message-composer.css.js +6 -0
- package/dist/inputs/message-composer/message-composer.css.js.map +1 -0
- package/dist/inputs/message-composer/message-composer.d.ts +139 -0
- package/dist/inputs/message-composer/message-composer.d.ts.map +1 -0
- package/dist/inputs/shared/field-binding.cjs +1 -1
- package/dist/inputs/shared/field-binding.cjs.map +1 -1
- package/dist/inputs/shared/field-binding.d.ts +15 -0
- package/dist/inputs/shared/field-binding.d.ts.map +1 -1
- package/dist/inputs/shared/field-binding.js +4 -3
- package/dist/inputs/shared/field-binding.js.map +1 -1
- package/dist/inputs/shared/form-context.cjs.map +1 -1
- package/dist/inputs/shared/form-context.d.ts +6 -0
- package/dist/inputs/shared/form-context.d.ts.map +1 -1
- package/dist/inputs/shared/form-context.js.map +1 -1
- package/dist/inputs/textarea/textarea.d.ts.map +1 -1
- package/dist/layout/navbar/navbar.css.cjs +1 -1
- package/dist/layout/navbar/navbar.css.cjs.map +1 -1
- package/dist/layout/navbar/navbar.css.js +1 -1
- package/dist/layout/navbar/navbar.css.js.map +1 -1
- package/dist/message-composer.cjs +52 -0
- package/dist/message-composer.cjs.map +1 -0
- package/dist/message-composer.js +168 -0
- package/dist/message-composer.js.map +1 -0
- package/dist/ore/dist/base-element.cjs +1 -1
- package/dist/ore/dist/base-element.cjs.map +1 -1
- package/dist/ore/dist/base-element.js +13 -3
- package/dist/ore/dist/base-element.js.map +1 -1
- package/dist/ore/dist/forms/field.cjs +1 -1
- package/dist/ore/dist/forms/field.cjs.map +1 -1
- package/dist/ore/dist/forms/field.js +29 -22
- package/dist/ore/dist/forms/field.js.map +1 -1
- package/dist/ore/dist/runtime.cjs +1 -1
- package/dist/ore/dist/runtime.cjs.map +1 -1
- package/dist/ore/dist/runtime.js +3 -1
- package/dist/ore/dist/runtime.js.map +1 -1
- package/dist/radio-group.cjs +9 -9
- package/dist/radio-group.cjs.map +1 -1
- package/dist/radio-group.js +44 -38
- package/dist/radio-group.js.map +1 -1
- package/dist/radio.cjs +3 -3
- package/dist/radio.cjs.map +1 -1
- package/dist/radio.js +23 -24
- package/dist/radio.js.map +1 -1
- package/dist/refine.cjs +228 -178
- package/dist/refine.cjs.map +1 -1
- package/dist/refine.iife.js +228 -178
- package/dist/refine.iife.js.map +1 -1
- package/dist/refine.js +251 -201
- package/dist/refine.js.map +1 -1
- package/dist/select.cjs +31 -31
- package/dist/select.cjs.map +1 -1
- package/dist/select.js +125 -122
- package/dist/select.js.map +1 -1
- package/dist/shared/size-presets.cjs +1 -1
- package/dist/shared/size-presets.cjs.map +1 -1
- package/dist/shared/size-presets.d.ts +23 -0
- package/dist/shared/size-presets.d.ts.map +1 -1
- package/dist/shared/size-presets.js +17 -1
- package/dist/shared/size-presets.js.map +1 -1
- package/dist/switch.cjs +3 -3
- package/dist/switch.cjs.map +1 -1
- package/dist/switch.js +17 -18
- package/dist/switch.js.map +1 -1
- package/dist/textarea.cjs +15 -15
- package/dist/textarea.cjs.map +1 -1
- package/dist/textarea.js +64 -60
- package/dist/textarea.js.map +1 -1
- package/package.json +22 -10
|
@@ -77,6 +77,22 @@ var e = {
|
|
|
77
77
|
size: "var(--size-4)"
|
|
78
78
|
}
|
|
79
79
|
}, a = {
|
|
80
|
+
lg: {
|
|
81
|
+
"--_padding": "var(--size-4)",
|
|
82
|
+
fontSize: "var(--text-base)",
|
|
83
|
+
gap: "var(--size-2-5)"
|
|
84
|
+
},
|
|
85
|
+
md: {
|
|
86
|
+
"--_padding": "var(--size-3)",
|
|
87
|
+
fontSize: "var(--text-sm)",
|
|
88
|
+
gap: "var(--size-2)"
|
|
89
|
+
},
|
|
90
|
+
sm: {
|
|
91
|
+
"--_padding": "var(--size-2)",
|
|
92
|
+
fontSize: "var(--text-xs)",
|
|
93
|
+
gap: "var(--size-1-5)"
|
|
94
|
+
}
|
|
95
|
+
}, o = {
|
|
80
96
|
lg: {
|
|
81
97
|
"--_min-height": "var(--size-40)",
|
|
82
98
|
fontSize: "var(--text-base)"
|
|
@@ -91,6 +107,6 @@ var e = {
|
|
|
91
107
|
}
|
|
92
108
|
};
|
|
93
109
|
//#endregion
|
|
94
|
-
export { n as CONTROL_SIZE_PRESET, e as FIELD_SIZE_PRESET,
|
|
110
|
+
export { n as CONTROL_SIZE_PRESET, e as FIELD_SIZE_PRESET, o as FILE_INPUT_SIZE_PRESET, a as MESSAGE_COMPOSER_SIZE_PRESET, i as SLIDER_SIZE_PRESET, r as SWITCH_SIZE_PRESET, t as TEXTAREA_SIZE_PRESET };
|
|
95
111
|
|
|
96
112
|
//# sourceMappingURL=size-presets.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"size-presets.js","names":[],"sources":["../../src/shared/size-presets.ts"],"sourcesContent":["import type { SizeConfig } from '../styles/mixins/shape.css';\nimport type { ComponentSize } from './types';\n\n/** A preset with an entry for every ComponentSize key. */\ntype FullSizePreset = Record<ComponentSize, SizeConfig>;\n\n/** A preset that may omit some ComponentSize keys (sizeVariantMixin fills the gaps with its defaults). */\ntype PartialSizePreset = Partial<Record<ComponentSize, SizeConfig>>;\n\nexport const FIELD_SIZE_PRESET = {\n lg: {\n '--_field-height': 'var(--size-12)',\n '--_padding': 'var(--size-2-5) var(--size-3-5)',\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n },\n md: {\n '--_field-height': 'var(--size-10)',\n '--_padding': 'var(--size-1-5) var(--size-3)',\n fontSize: 'var(--text-sm)',\n gap: 'var(--size-2)',\n },\n sm: {\n '--_field-height': 'var(--size-8)',\n '--_padding': 'var(--size-1) var(--size-2)',\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-1-5)',\n },\n} satisfies FullSizePreset;\n\nexport const TEXTAREA_SIZE_PRESET = {\n lg: {\n '--_padding': 'var(--size-2-5) var(--size-3-5)',\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n },\n md: {\n '--_padding': 'var(--size-1-5) var(--size-3)',\n fontSize: 'var(--text-sm)',\n gap: 'var(--size-2)',\n },\n sm: {\n '--_padding': 'var(--size-1) var(--size-2)',\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-1-5)',\n },\n} satisfies FullSizePreset;\n\n/** Shared size preset for checkbox and radio (icon + label layout). */\nexport const CONTROL_SIZE_PRESET = {\n lg: {\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n size: 'var(--size-6)',\n },\n sm: {\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-1-5)',\n size: 'var(--size-4)',\n },\n} satisfies PartialSizePreset;\n\n/** Shared size preset for the switch toggle control. */\nexport const SWITCH_SIZE_PRESET = {\n lg: {\n fontSize: 'var(--text-base)',\n gap: 'var(--size-3)',\n height: 'var(--size-7)',\n thumbSize: 'var(--size-6)',\n width: 'var(--size-14)',\n },\n sm: {\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-2)',\n height: 'var(--size-5)',\n thumbSize: 'var(--size-4)',\n width: 'var(--size-9)',\n },\n} satisfies PartialSizePreset;\n\n/** Shared size preset for the slider track/thumb. */\nexport const SLIDER_SIZE_PRESET = {\n lg: {\n fontSize: 'var(--text-base)',\n height: 'calc(var(--size-5) - var(--size-1))',\n size: 'var(--size-5)',\n },\n md: {\n fontSize: 'var(--text-base)',\n height: 'var(--size-3)',\n size: 'var(--size-5)',\n },\n sm: {\n fontSize: 'var(--text-xs)',\n height: 'var(--size-2)',\n size: 'var(--size-4)',\n },\n} satisfies FullSizePreset;\n\n/** Shared size preset for the file-input dropzone. */\nexport const FILE_INPUT_SIZE_PRESET = {\n lg: {\n '--_min-height': 'var(--size-40)',\n fontSize: 'var(--text-base)',\n },\n md: {\n '--_min-height': 'var(--size-32)',\n fontSize: 'var(--text-sm)',\n },\n sm: {\n '--_min-height': 'var(--size-28)',\n fontSize: 'var(--text-xs)',\n },\n} satisfies FullSizePreset;\n"],"mappings":";AASA,IAAa,IAAoB;CAC/B,IAAI;EACF,mBAAmB;EACnB,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,mBAAmB;EACnB,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,mBAAmB;EACnB,cAAc;EACd,UAAU;EACV,KAAK;CACP;AACF,GAEa,IAAuB;CAClC,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;AACF,GAGa,IAAsB;CACjC,IAAI;EACF,UAAU;EACV,KAAK;EACL,MAAM;CACR;CACA,IAAI;EACF,UAAU;EACV,KAAK;EACL,MAAM;CACR;AACF,GAGa,IAAqB;CAChC,IAAI;EACF,UAAU;EACV,KAAK;EACL,QAAQ;EACR,WAAW;EACX,OAAO;CACT;CACA,IAAI;EACF,UAAU;EACV,KAAK;EACL,QAAQ;EACR,WAAW;EACX,OAAO;CACT;AACF,GAGa,IAAqB;CAChC,IAAI;EACF,UAAU;EACV,QAAQ;EACR,MAAM;CACR;CACA,IAAI;EACF,UAAU;EACV,QAAQ;EACR,MAAM;CACR;CACA,IAAI;EACF,UAAU;EACV,QAAQ;EACR,MAAM;CACR;AACF,GAGa,IAAyB;CACpC,IAAI;EACF,iBAAiB;EACjB,UAAU;CACZ;CACA,IAAI;EACF,iBAAiB;EACjB,UAAU;CACZ;CACA,IAAI;EACF,iBAAiB;EACjB,UAAU;CACZ;AACF"}
|
|
1
|
+
{"version":3,"file":"size-presets.js","names":[],"sources":["../../src/shared/size-presets.ts"],"sourcesContent":["import type { SizeConfig } from '../styles/mixins/shape.css';\nimport type { ComponentSize } from './types';\n\n/** A preset with an entry for every ComponentSize key. */\ntype FullSizePreset = Record<ComponentSize, SizeConfig>;\n\n/** A preset that may omit some ComponentSize keys (sizeVariantMixin fills the gaps with its defaults). */\ntype PartialSizePreset = Partial<Record<ComponentSize, SizeConfig>>;\n\nexport const FIELD_SIZE_PRESET = {\n lg: {\n '--_field-height': 'var(--size-12)',\n '--_padding': 'var(--size-2-5) var(--size-3-5)',\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n },\n md: {\n '--_field-height': 'var(--size-10)',\n '--_padding': 'var(--size-1-5) var(--size-3)',\n fontSize: 'var(--text-sm)',\n gap: 'var(--size-2)',\n },\n sm: {\n '--_field-height': 'var(--size-8)',\n '--_padding': 'var(--size-1) var(--size-2)',\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-1-5)',\n },\n} satisfies FullSizePreset;\n\nexport const TEXTAREA_SIZE_PRESET = {\n lg: {\n '--_padding': 'var(--size-2-5) var(--size-3-5)',\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n },\n md: {\n '--_padding': 'var(--size-1-5) var(--size-3)',\n fontSize: 'var(--text-sm)',\n gap: 'var(--size-2)',\n },\n sm: {\n '--_padding': 'var(--size-1) var(--size-2)',\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-1-5)',\n },\n} satisfies FullSizePreset;\n\n/** Shared size preset for checkbox and radio (icon + label layout). */\nexport const CONTROL_SIZE_PRESET = {\n lg: {\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n size: 'var(--size-6)',\n },\n sm: {\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-1-5)',\n size: 'var(--size-4)',\n },\n} satisfies PartialSizePreset;\n\n/** Shared size preset for the switch toggle control. */\nexport const SWITCH_SIZE_PRESET = {\n lg: {\n fontSize: 'var(--text-base)',\n gap: 'var(--size-3)',\n height: 'var(--size-7)',\n thumbSize: 'var(--size-6)',\n width: 'var(--size-14)',\n },\n sm: {\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-2)',\n height: 'var(--size-5)',\n thumbSize: 'var(--size-4)',\n width: 'var(--size-9)',\n },\n} satisfies PartialSizePreset;\n\n/** Shared size preset for the slider track/thumb. */\nexport const SLIDER_SIZE_PRESET = {\n lg: {\n fontSize: 'var(--text-base)',\n height: 'calc(var(--size-5) - var(--size-1))',\n size: 'var(--size-5)',\n },\n md: {\n fontSize: 'var(--text-base)',\n height: 'var(--size-3)',\n size: 'var(--size-5)',\n },\n sm: {\n fontSize: 'var(--text-xs)',\n height: 'var(--size-2)',\n size: 'var(--size-4)',\n },\n} satisfies FullSizePreset;\n\n/**\n * Size preset for the message composer card. Padding is symmetric (unlike\n * `TEXTAREA_SIZE_PRESET`'s field-shaped padding) since this scales a card that wraps a field\n * *and* a toolbar row, not a bare field — `md`'s padding matches the value the card used before\n * `size` scaled anything, so the default look is unchanged.\n */\nexport const MESSAGE_COMPOSER_SIZE_PRESET = {\n lg: {\n '--_padding': 'var(--size-4)',\n fontSize: 'var(--text-base)',\n gap: 'var(--size-2-5)',\n },\n md: {\n '--_padding': 'var(--size-3)',\n fontSize: 'var(--text-sm)',\n gap: 'var(--size-2)',\n },\n sm: {\n '--_padding': 'var(--size-2)',\n fontSize: 'var(--text-xs)',\n gap: 'var(--size-1-5)',\n },\n} satisfies FullSizePreset;\n\n/** Shared size preset for the file-input dropzone. */\nexport const FILE_INPUT_SIZE_PRESET = {\n lg: {\n '--_min-height': 'var(--size-40)',\n fontSize: 'var(--text-base)',\n },\n md: {\n '--_min-height': 'var(--size-32)',\n fontSize: 'var(--text-sm)',\n },\n sm: {\n '--_min-height': 'var(--size-28)',\n fontSize: 'var(--text-xs)',\n },\n} satisfies FullSizePreset;\n"],"mappings":";AASA,IAAa,IAAoB;CAC/B,IAAI;EACF,mBAAmB;EACnB,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,mBAAmB;EACnB,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,mBAAmB;EACnB,cAAc;EACd,UAAU;EACV,KAAK;CACP;AACF,GAEa,IAAuB;CAClC,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;AACF,GAGa,IAAsB;CACjC,IAAI;EACF,UAAU;EACV,KAAK;EACL,MAAM;CACR;CACA,IAAI;EACF,UAAU;EACV,KAAK;EACL,MAAM;CACR;AACF,GAGa,IAAqB;CAChC,IAAI;EACF,UAAU;EACV,KAAK;EACL,QAAQ;EACR,WAAW;EACX,OAAO;CACT;CACA,IAAI;EACF,UAAU;EACV,KAAK;EACL,QAAQ;EACR,WAAW;EACX,OAAO;CACT;AACF,GAGa,IAAqB;CAChC,IAAI;EACF,UAAU;EACV,QAAQ;EACR,MAAM;CACR;CACA,IAAI;EACF,UAAU;EACV,QAAQ;EACR,MAAM;CACR;CACA,IAAI;EACF,UAAU;EACV,QAAQ;EACR,MAAM;CACR;AACF,GAQa,IAA+B;CAC1C,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;CACA,IAAI;EACF,cAAc;EACd,UAAU;EACV,KAAK;CACP;AACF,GAGa,IAAyB;CACpC,IAAI;EACF,iBAAiB;EACjB,UAAU;CACZ;CACA,IAAI;EACF,iBAAiB;EACjB,UAAU;CACZ;CACA,IAAI;EACF,iBAAiB;EACjB,UAAU;CACZ;AACF"}
|
package/dist/switch.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/states.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./shared/prop-bundles.cjs"),i=require("./shared/size-presets.cjs"),a=require("./headless/ore.cjs"),o=require("./headless/checkable.cjs"),s=require("./ore/dist/forms/field.cjs");require("./ore/dist/forms.cjs");const c=require("./inputs/shared/field-binding.cjs"),l=require("./inputs/shared/form-context.cjs"),u=require("./inputs/shared/templates.cjs"),d=require("./inputs/switch/switch.css.cjs");let f=require("@vielzeug/ore");var p=`ore-switch`;(0,f.define)(p,{formAssociated:!0,props:{...r.themableBundle,...r.sizableBundle,...r.disablableBundle,checked:f.prop.bool(!1),error:f.prop.string(),helper:f.prop.string(),name:f.prop.string(),value:f.prop.string(`on`)},setup(e){let t=(0,f.useEmit)(),n=(0,f.inject)(l.FORM_CTX),r=l.useFormContext(e,n),i=
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./styles/mixins/shape.css.cjs"),t=require("./styles/mixins/states.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./shared/prop-bundles.cjs"),i=require("./shared/size-presets.cjs"),a=require("./headless/ore.cjs"),o=require("./headless/checkable.cjs"),s=require("./ore/dist/forms/field.cjs");require("./ore/dist/forms.cjs");const c=require("./inputs/shared/field-binding.cjs"),l=require("./inputs/shared/form-context.cjs"),u=require("./inputs/shared/templates.cjs"),d=require("./inputs/switch/switch.css.cjs");let f=require("@vielzeug/ore");var p=`ore-switch`;(0,f.define)(p,{formAssociated:!0,props:{...r.themableBundle,...r.sizableBundle,...r.disablableBundle,checked:f.prop.bool(!1),error:f.prop.string(),helper:f.prop.string(),name:f.prop.string(),value:f.prop.string(`on`)},setup(e){let t=(0,f.useEmit)(),n=(0,f.inject)(l.FORM_CTX),r=l.useFormContext(e,n),i=o.createCheckable({checked:e.checked,clearIndeterminateFirst:!1,disabled:r.disabled,error:e.error,helper:e.helper,onToggle:e=>{i.triggerValidation(`change`),t(`change`,e)},prefix:`switch`,signal:a.lifecycleSignal(f.onCleanup),validateOn:n?.validateOn,value:e.value});i.attachFormField(s.useField({disabled:i.disabled,toFormValue:e=>e,value:i.checkableFormValue}));let{assistiveId:d,checked:p,disabled:m,errorText:h,handleClick:g,handleKeydown:_,helperText:v,labelId:y}=i;return c.applyCheckableBinding(r.size,{assistiveId:d,checked:p,disabled:m,errorText:h,handleClick:g,handleKeydown:_,helperText:v,labelId:y},`switch`),f.html`
|
|
2
2
|
<div class="switch-wrapper" part="switch">
|
|
3
3
|
<div class="switch-track" part="track">
|
|
4
4
|
<div class="switch-thumb" part="thumb"></div>
|
|
5
5
|
</div>
|
|
6
6
|
</div>
|
|
7
|
-
<span class="label" part="label" id="${
|
|
8
|
-
${u.renderHelperRegion(
|
|
7
|
+
<span class="label" part="label" id="${y}"><slot></slot></span>
|
|
8
|
+
${u.renderHelperRegion(d,h,v)}
|
|
9
9
|
`},styles:[n.colorThemeMixin,n.forcedColorsFormControlMixin,t.disabledStateMixin,e.sizeVariantMixin(i.SWITCH_SIZE_PRESET),d.default]}),exports.SWITCH_TAG=p;
|
|
10
10
|
//# sourceMappingURL=switch.cjs.map
|
package/dist/switch.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.cjs","names":[],"sources":["../src/inputs/switch/switch.ts"],"sourcesContent":["import { define, html, inject, prop, onCleanup, useEmit } from '@vielzeug/ore';\nimport { useField } from '@vielzeug/ore/forms';\n\nimport type { CheckableProps, ComponentSize, ThemeColor } from '../../types';\n\nimport { type CheckableChangePayload, lifecycleSignal, createCheckable } from '../../headless';\nimport { disablableBundle, sizableBundle, SWITCH_SIZE_PRESET, themableBundle } from '../../shared';\nimport { colorThemeMixin, disabledStateMixin, forcedColorsFormControlMixin, sizeVariantMixin } from '../../styles';\nimport { applyCheckableBinding } from '../shared/field-binding';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport { renderHelperRegion } from '../shared/templates';\nimport componentStyles from './switch.css?inline';\n\nexport type OreSwitchEvents = {\n change: CheckableChangePayload;\n};\n\nexport type OreSwitchProps = CheckableProps & {\n /** Theme color */\n color?: ThemeColor;\n /** Disable interaction */\n disabled?: boolean;\n /** Error message (marks field as invalid) */\n error?: string;\n /** Helper text displayed below the switch */\n helper?: string;\n /** Component size */\n size?: ComponentSize;\n};\n\n/**\n * A toggle switch component for binary on/off states.\n *\n * @element ore-switch\n *\n * @attr {boolean} checked - Checked/on state\n * @attr {boolean} disabled - Disable switch interaction\n * @attr {string} value - Field value\n * @attr {string} name - Form field name\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Switch size: 'sm' | 'md' | 'lg'\n * @attr {string} error - Error message (marks field as invalid)\n * @attr {string} helper - Helper text displayed below the switch\n *\n * @fires change - Emitted when switch is toggled. detail: { checked: boolean, value: string, originalEvent?: Event }\n *\n * @slot - Switch label text\n *\n * @cssprop --switch-width - Track width\n * @cssprop --switch-height - Track height\n * @cssprop --switch-track-bg - Inactive track background color\n * @cssprop --switch-checked-bg - Active/checked track background color\n * @cssprop --switch-thumb-bg - Thumb background color\n * @cssprop --switch-font-size - Label font size\n * @part switch - The switch wrapper element\n * @part track - The switch track element\n * @part thumb - The switch thumb element\n * @part label - The label element\n * @part helper-text - The helper/error text element\n *\n * @example\n * ```html\n * <ore-switch name=\"notifications\" checked color=\"primary\">Enable notifications</ore-switch>\n * <ore-switch name=\"darkMode\" size=\"sm\">Dark mode</ore-switch>\n * <ore-switch disabled helper=\"Contact admin to change\">Admin only</ore-switch>\n * ```\n */\nexport const SWITCH_TAG = 'ore-switch' as const;\ndefine<OreSwitchProps>(SWITCH_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n checked: prop.bool(false),\n error: prop.string(),\n helper: prop.string(),\n name: prop.string(),\n value: prop.string('on'),\n },\n setup(props) {\n const emit = useEmit<OreSwitchEvents>();\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n
|
|
1
|
+
{"version":3,"file":"switch.cjs","names":[],"sources":["../src/inputs/switch/switch.ts"],"sourcesContent":["import { define, html, inject, prop, onCleanup, useEmit } from '@vielzeug/ore';\nimport { useField } from '@vielzeug/ore/forms';\n\nimport type { CheckableProps, ComponentSize, ThemeColor } from '../../types';\n\nimport { type CheckableChangePayload, lifecycleSignal, createCheckable } from '../../headless';\nimport { disablableBundle, sizableBundle, SWITCH_SIZE_PRESET, themableBundle } from '../../shared';\nimport { colorThemeMixin, disabledStateMixin, forcedColorsFormControlMixin, sizeVariantMixin } from '../../styles';\nimport { applyCheckableBinding } from '../shared/field-binding';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport { renderHelperRegion } from '../shared/templates';\nimport componentStyles from './switch.css?inline';\n\nexport type OreSwitchEvents = {\n change: CheckableChangePayload;\n};\n\nexport type OreSwitchProps = CheckableProps & {\n /** Theme color */\n color?: ThemeColor;\n /** Disable interaction */\n disabled?: boolean;\n /** Error message (marks field as invalid) */\n error?: string;\n /** Helper text displayed below the switch */\n helper?: string;\n /** Component size */\n size?: ComponentSize;\n};\n\n/**\n * A toggle switch component for binary on/off states.\n *\n * @element ore-switch\n *\n * @attr {boolean} checked - Checked/on state\n * @attr {boolean} disabled - Disable switch interaction\n * @attr {string} value - Field value\n * @attr {string} name - Form field name\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Switch size: 'sm' | 'md' | 'lg'\n * @attr {string} error - Error message (marks field as invalid)\n * @attr {string} helper - Helper text displayed below the switch\n *\n * @fires change - Emitted when switch is toggled. detail: { checked: boolean, value: string, originalEvent?: Event }\n *\n * @slot - Switch label text\n *\n * @cssprop --switch-width - Track width\n * @cssprop --switch-height - Track height\n * @cssprop --switch-track-bg - Inactive track background color\n * @cssprop --switch-checked-bg - Active/checked track background color\n * @cssprop --switch-thumb-bg - Thumb background color\n * @cssprop --switch-font-size - Label font size\n * @part switch - The switch wrapper element\n * @part track - The switch track element\n * @part thumb - The switch thumb element\n * @part label - The label element\n * @part helper-text - The helper/error text element\n *\n * @example\n * ```html\n * <ore-switch name=\"notifications\" checked color=\"primary\">Enable notifications</ore-switch>\n * <ore-switch name=\"darkMode\" size=\"sm\">Dark mode</ore-switch>\n * <ore-switch disabled helper=\"Contact admin to change\">Admin only</ore-switch>\n * ```\n */\nexport const SWITCH_TAG = 'ore-switch' as const;\ndefine<OreSwitchProps>(SWITCH_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n checked: prop.bool(false),\n error: prop.string(),\n helper: prop.string(),\n name: prop.string(),\n value: prop.string('on'),\n },\n setup(props) {\n const emit = useEmit<OreSwitchEvents>();\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n const checkable = createCheckable({\n checked: props.checked,\n clearIndeterminateFirst: false,\n disabled: fCtxProps.disabled,\n error: props.error,\n helper: props.helper,\n onToggle: (payload) => {\n checkable.triggerValidation('change');\n emit('change', payload);\n },\n prefix: 'switch',\n signal: lifecycleSignal(onCleanup),\n validateOn: formCtx?.validateOn,\n value: props.value,\n });\n\n checkable.attachFormField(\n useField<string | null>({\n disabled: checkable.disabled,\n toFormValue: (v) => v,\n value: checkable.checkableFormValue,\n }),\n );\n\n const { assistiveId, checked, disabled, errorText, handleClick, handleKeydown, helperText, labelId } = checkable;\n\n applyCheckableBinding(\n fCtxProps.size,\n { assistiveId, checked, disabled, errorText, handleClick, handleKeydown, helperText, labelId },\n 'switch',\n );\n\n return html`\n <div class=\"switch-wrapper\" part=\"switch\">\n <div class=\"switch-track\" part=\"track\">\n <div class=\"switch-thumb\" part=\"thumb\"></div>\n </div>\n </div>\n <span class=\"label\" part=\"label\" id=\"${labelId}\"><slot></slot></span>\n ${renderHelperRegion(assistiveId, errorText, helperText)}\n `;\n },\n styles: [\n colorThemeMixin,\n forcedColorsFormControlMixin,\n disabledStateMixin,\n sizeVariantMixin(SWITCH_SIZE_PRESET),\n componentStyles,\n ],\n});\n"],"mappings":"goBAmEA,IAAa,EAAa,0BACH,EAAY,CACjC,eAAgB,GAChB,MAAO,CACL,GAAG,EAAA,eACH,GAAG,EAAA,cACH,GAAG,EAAA,iBACH,QAAS,EAAA,KAAK,KAAK,EAAK,EACxB,MAAO,EAAA,KAAK,OAAO,EACnB,OAAQ,EAAA,KAAK,OAAO,EACpB,KAAM,EAAA,KAAK,OAAO,EAClB,MAAO,EAAA,KAAK,OAAO,IAAI,CACzB,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAA,EAAA,QAAA,CAAgC,EAEhC,GAAA,EAAA,EAAA,OAAA,CAAiB,EAAA,QAAQ,EACzB,EAAY,EAAA,eAAe,EAAO,CAAO,EAEzC,EAAY,EAAA,gBAAgB,CAChC,QAAS,EAAM,QACf,wBAAyB,GACzB,SAAU,EAAU,SACpB,MAAO,EAAM,MACb,OAAQ,EAAM,OACd,SAAW,GAAY,CACrB,EAAU,kBAAkB,QAAQ,EACpC,EAAK,SAAU,CAAO,CACxB,EACA,OAAQ,SACR,OAAQ,EAAA,gBAAgB,EAAA,SAAS,EACjC,WAAY,GAAS,WACrB,MAAO,EAAM,KACf,CAAC,EAED,EAAU,gBACR,EAAA,SAAwB,CACtB,SAAU,EAAU,SACpB,YAAc,GAAM,EACpB,MAAO,EAAU,kBACnB,CAAC,CACH,EAEA,GAAM,CAAE,cAAa,UAAS,WAAU,YAAW,cAAa,gBAAe,aAAY,WAAY,EAQvG,OANA,EAAA,sBACE,EAAU,KACV,CAAE,cAAa,UAAS,WAAU,YAAW,cAAa,gBAAe,aAAY,SAAQ,EAC7F,QACF,EAEO,EAAA,IAAI;;;;;;6CAM8B,EAAQ;QAC7C,EAAA,mBAAmB,EAAa,EAAW,CAAU,EAAE;KAE7D,EACA,OAAQ,CACN,EAAA,gBACA,EAAA,6BACA,EAAA,mBACA,EAAA,iBAAiB,EAAA,kBAAkB,EACnC,EAAA,OACF,CACF,CAAC"}
|
package/dist/switch.js
CHANGED
|
@@ -27,44 +27,43 @@ g(S, {
|
|
|
27
27
|
value: b.string("on")
|
|
28
28
|
},
|
|
29
29
|
setup(e) {
|
|
30
|
-
let t = x(), n = v(f), r = p(e, n), i =
|
|
30
|
+
let t = x(), n = v(f), r = p(e, n), i = l({
|
|
31
31
|
checked: e.checked,
|
|
32
32
|
clearIndeterminateFirst: !1,
|
|
33
33
|
disabled: r.disabled,
|
|
34
34
|
error: e.error,
|
|
35
|
-
getFormField: () => i,
|
|
36
35
|
helper: e.helper,
|
|
37
36
|
onToggle: (e) => {
|
|
38
|
-
|
|
37
|
+
i.triggerValidation("change"), t("change", e);
|
|
39
38
|
},
|
|
40
39
|
prefix: "switch",
|
|
41
40
|
signal: c(y),
|
|
42
41
|
validateOn: n?.validateOn,
|
|
43
42
|
value: e.value
|
|
44
43
|
});
|
|
45
|
-
i
|
|
46
|
-
disabled:
|
|
44
|
+
i.attachFormField(u({
|
|
45
|
+
disabled: i.disabled,
|
|
47
46
|
toFormValue: (e) => e,
|
|
48
|
-
value:
|
|
49
|
-
});
|
|
50
|
-
let { assistiveId:
|
|
47
|
+
value: i.checkableFormValue
|
|
48
|
+
}));
|
|
49
|
+
let { assistiveId: a, checked: o, disabled: s, errorText: h, handleClick: g, handleKeydown: b, helperText: S, labelId: C } = i;
|
|
51
50
|
return d(r.size, {
|
|
52
|
-
assistiveId:
|
|
53
|
-
checked:
|
|
54
|
-
disabled:
|
|
55
|
-
errorText:
|
|
56
|
-
handleClick:
|
|
57
|
-
handleKeydown:
|
|
58
|
-
helperText:
|
|
59
|
-
labelId:
|
|
51
|
+
assistiveId: a,
|
|
52
|
+
checked: o,
|
|
53
|
+
disabled: s,
|
|
54
|
+
errorText: h,
|
|
55
|
+
handleClick: g,
|
|
56
|
+
handleKeydown: b,
|
|
57
|
+
helperText: S,
|
|
58
|
+
labelId: C
|
|
60
59
|
}, "switch"), _`
|
|
61
60
|
<div class="switch-wrapper" part="switch">
|
|
62
61
|
<div class="switch-track" part="track">
|
|
63
62
|
<div class="switch-thumb" part="thumb"></div>
|
|
64
63
|
</div>
|
|
65
64
|
</div>
|
|
66
|
-
<span class="label" part="label" id="${
|
|
67
|
-
${m(
|
|
65
|
+
<span class="label" part="label" id="${C}"><slot></slot></span>
|
|
66
|
+
${m(a, h, S)}
|
|
68
67
|
`;
|
|
69
68
|
},
|
|
70
69
|
styles: [
|
package/dist/switch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.js","names":[],"sources":["../src/inputs/switch/switch.ts"],"sourcesContent":["import { define, html, inject, prop, onCleanup, useEmit } from '@vielzeug/ore';\nimport { useField } from '@vielzeug/ore/forms';\n\nimport type { CheckableProps, ComponentSize, ThemeColor } from '../../types';\n\nimport { type CheckableChangePayload, lifecycleSignal, createCheckable } from '../../headless';\nimport { disablableBundle, sizableBundle, SWITCH_SIZE_PRESET, themableBundle } from '../../shared';\nimport { colorThemeMixin, disabledStateMixin, forcedColorsFormControlMixin, sizeVariantMixin } from '../../styles';\nimport { applyCheckableBinding } from '../shared/field-binding';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport { renderHelperRegion } from '../shared/templates';\nimport componentStyles from './switch.css?inline';\n\nexport type OreSwitchEvents = {\n change: CheckableChangePayload;\n};\n\nexport type OreSwitchProps = CheckableProps & {\n /** Theme color */\n color?: ThemeColor;\n /** Disable interaction */\n disabled?: boolean;\n /** Error message (marks field as invalid) */\n error?: string;\n /** Helper text displayed below the switch */\n helper?: string;\n /** Component size */\n size?: ComponentSize;\n};\n\n/**\n * A toggle switch component for binary on/off states.\n *\n * @element ore-switch\n *\n * @attr {boolean} checked - Checked/on state\n * @attr {boolean} disabled - Disable switch interaction\n * @attr {string} value - Field value\n * @attr {string} name - Form field name\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Switch size: 'sm' | 'md' | 'lg'\n * @attr {string} error - Error message (marks field as invalid)\n * @attr {string} helper - Helper text displayed below the switch\n *\n * @fires change - Emitted when switch is toggled. detail: { checked: boolean, value: string, originalEvent?: Event }\n *\n * @slot - Switch label text\n *\n * @cssprop --switch-width - Track width\n * @cssprop --switch-height - Track height\n * @cssprop --switch-track-bg - Inactive track background color\n * @cssprop --switch-checked-bg - Active/checked track background color\n * @cssprop --switch-thumb-bg - Thumb background color\n * @cssprop --switch-font-size - Label font size\n * @part switch - The switch wrapper element\n * @part track - The switch track element\n * @part thumb - The switch thumb element\n * @part label - The label element\n * @part helper-text - The helper/error text element\n *\n * @example\n * ```html\n * <ore-switch name=\"notifications\" checked color=\"primary\">Enable notifications</ore-switch>\n * <ore-switch name=\"darkMode\" size=\"sm\">Dark mode</ore-switch>\n * <ore-switch disabled helper=\"Contact admin to change\">Admin only</ore-switch>\n * ```\n */\nexport const SWITCH_TAG = 'ore-switch' as const;\ndefine<OreSwitchProps>(SWITCH_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n checked: prop.bool(false),\n error: prop.string(),\n helper: prop.string(),\n name: prop.string(),\n value: prop.string('on'),\n },\n setup(props) {\n const emit = useEmit<OreSwitchEvents>();\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n
|
|
1
|
+
{"version":3,"file":"switch.js","names":[],"sources":["../src/inputs/switch/switch.ts"],"sourcesContent":["import { define, html, inject, prop, onCleanup, useEmit } from '@vielzeug/ore';\nimport { useField } from '@vielzeug/ore/forms';\n\nimport type { CheckableProps, ComponentSize, ThemeColor } from '../../types';\n\nimport { type CheckableChangePayload, lifecycleSignal, createCheckable } from '../../headless';\nimport { disablableBundle, sizableBundle, SWITCH_SIZE_PRESET, themableBundle } from '../../shared';\nimport { colorThemeMixin, disabledStateMixin, forcedColorsFormControlMixin, sizeVariantMixin } from '../../styles';\nimport { applyCheckableBinding } from '../shared/field-binding';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport { renderHelperRegion } from '../shared/templates';\nimport componentStyles from './switch.css?inline';\n\nexport type OreSwitchEvents = {\n change: CheckableChangePayload;\n};\n\nexport type OreSwitchProps = CheckableProps & {\n /** Theme color */\n color?: ThemeColor;\n /** Disable interaction */\n disabled?: boolean;\n /** Error message (marks field as invalid) */\n error?: string;\n /** Helper text displayed below the switch */\n helper?: string;\n /** Component size */\n size?: ComponentSize;\n};\n\n/**\n * A toggle switch component for binary on/off states.\n *\n * @element ore-switch\n *\n * @attr {boolean} checked - Checked/on state\n * @attr {boolean} disabled - Disable switch interaction\n * @attr {string} value - Field value\n * @attr {string} name - Form field name\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} size - Switch size: 'sm' | 'md' | 'lg'\n * @attr {string} error - Error message (marks field as invalid)\n * @attr {string} helper - Helper text displayed below the switch\n *\n * @fires change - Emitted when switch is toggled. detail: { checked: boolean, value: string, originalEvent?: Event }\n *\n * @slot - Switch label text\n *\n * @cssprop --switch-width - Track width\n * @cssprop --switch-height - Track height\n * @cssprop --switch-track-bg - Inactive track background color\n * @cssprop --switch-checked-bg - Active/checked track background color\n * @cssprop --switch-thumb-bg - Thumb background color\n * @cssprop --switch-font-size - Label font size\n * @part switch - The switch wrapper element\n * @part track - The switch track element\n * @part thumb - The switch thumb element\n * @part label - The label element\n * @part helper-text - The helper/error text element\n *\n * @example\n * ```html\n * <ore-switch name=\"notifications\" checked color=\"primary\">Enable notifications</ore-switch>\n * <ore-switch name=\"darkMode\" size=\"sm\">Dark mode</ore-switch>\n * <ore-switch disabled helper=\"Contact admin to change\">Admin only</ore-switch>\n * ```\n */\nexport const SWITCH_TAG = 'ore-switch' as const;\ndefine<OreSwitchProps>(SWITCH_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n checked: prop.bool(false),\n error: prop.string(),\n helper: prop.string(),\n name: prop.string(),\n value: prop.string('on'),\n },\n setup(props) {\n const emit = useEmit<OreSwitchEvents>();\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n const checkable = createCheckable({\n checked: props.checked,\n clearIndeterminateFirst: false,\n disabled: fCtxProps.disabled,\n error: props.error,\n helper: props.helper,\n onToggle: (payload) => {\n checkable.triggerValidation('change');\n emit('change', payload);\n },\n prefix: 'switch',\n signal: lifecycleSignal(onCleanup),\n validateOn: formCtx?.validateOn,\n value: props.value,\n });\n\n checkable.attachFormField(\n useField<string | null>({\n disabled: checkable.disabled,\n toFormValue: (v) => v,\n value: checkable.checkableFormValue,\n }),\n );\n\n const { assistiveId, checked, disabled, errorText, handleClick, handleKeydown, helperText, labelId } = checkable;\n\n applyCheckableBinding(\n fCtxProps.size,\n { assistiveId, checked, disabled, errorText, handleClick, handleKeydown, helperText, labelId },\n 'switch',\n );\n\n return html`\n <div class=\"switch-wrapper\" part=\"switch\">\n <div class=\"switch-track\" part=\"track\">\n <div class=\"switch-thumb\" part=\"thumb\"></div>\n </div>\n </div>\n <span class=\"label\" part=\"label\" id=\"${labelId}\"><slot></slot></span>\n ${renderHelperRegion(assistiveId, errorText, helperText)}\n `;\n },\n styles: [\n colorThemeMixin,\n forcedColorsFormControlMixin,\n disabledStateMixin,\n sizeVariantMixin(SWITCH_SIZE_PRESET),\n componentStyles,\n ],\n});\n"],"mappings":";;;;;;;;;;;;;;;AAmEA,IAAa,IAAa;AAC1B,EAAuB,GAAY;CACjC,gBAAgB;CAChB,OAAO;EACL,GAAG;EACH,GAAG;EACH,GAAG;EACH,SAAS,EAAK,KAAK,EAAK;EACxB,OAAO,EAAK,OAAO;EACnB,QAAQ,EAAK,OAAO;EACpB,MAAM,EAAK,OAAO;EAClB,OAAO,EAAK,OAAO,IAAI;CACzB;CACA,MAAM,GAAO;EACX,IAAM,IAAO,EAAyB,GAEhC,IAAU,EAAO,CAAQ,GACzB,IAAY,EAAe,GAAO,CAAO,GAEzC,IAAY,EAAgB;GAChC,SAAS,EAAM;GACf,yBAAyB;GACzB,UAAU,EAAU;GACpB,OAAO,EAAM;GACb,QAAQ,EAAM;GACd,WAAW,MAAY;IAErB,AADA,EAAU,kBAAkB,QAAQ,GACpC,EAAK,UAAU,CAAO;GACxB;GACA,QAAQ;GACR,QAAQ,EAAgB,CAAS;GACjC,YAAY,GAAS;GACrB,OAAO,EAAM;EACf,CAAC;EAED,EAAU,gBACR,EAAwB;GACtB,UAAU,EAAU;GACpB,cAAc,MAAM;GACpB,OAAO,EAAU;EACnB,CAAC,CACH;EAEA,IAAM,EAAE,gBAAa,YAAS,aAAU,cAAW,gBAAa,kBAAe,eAAY,eAAY;EAQvG,OANA,EACE,EAAU,MACV;GAAE;GAAa;GAAS;GAAU;GAAW;GAAa;GAAe;GAAY;EAAQ,GAC7F,QACF,GAEO,CAAI;;;;;;6CAM8B,EAAQ;QAC7C,EAAmB,GAAa,GAAW,CAAU,EAAE;;CAE7D;CACA,QAAQ;EACN;EACA;EACA;EACA,EAAiB,CAAkB;EACnC;CACF;AACF,CAAC"}
|
package/dist/textarea.cjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./ore/dist/directives/live.cjs");require("./ore/dist/directives.cjs");const t=require("./styles/mixins/shape.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./styles/index.cjs"),i=require("./shared/prop-bundles.cjs"),a=require("./shared/size-presets.cjs"),o=require("./headless/ore.cjs"),s=require("./headless/text-field.cjs"),
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./ore/dist/directives/live.cjs");require("./ore/dist/directives.cjs");const t=require("./styles/mixins/shape.css.cjs"),n=require("./styles/mixins/theme.css.cjs"),r=require("./styles/index.cjs"),i=require("./shared/prop-bundles.cjs"),a=require("./shared/size-presets.cjs"),o=require("./headless/ore.cjs"),s=require("./headless/auto-resize.cjs"),c=require("./headless/field-base.cjs"),l=require("./headless/text-field.cjs"),u=require("./ore/dist/forms/field.cjs");require("./ore/dist/forms.cjs");const d=require("./inputs/shared/field-binding.cjs"),f=require("./inputs/shared/form-context.cjs"),p=require("./inputs/textarea/textarea.css.cjs");let m=require("@vielzeug/ore"),h=require("@vielzeug/ripple");var g=`ore-textarea`;(0,m.define)(g,{formAssociated:!0,props:{...i.themableBundle,...i.sizableBundle,...i.disablableBundle,...i.roundableBundle,"auto-resize":m.prop.bool(!1),error:m.prop.string(),fullwidth:m.prop.bool(!1),helper:m.prop.string(),label:m.prop.string(),"label-placement":m.prop.oneOf([`inset`,`outside`],`inset`),maxlength:m.prop.json(void 0),name:m.prop.string(),"no-resize":m.prop.bool(!1),placeholder:m.prop.string(),readonly:m.prop.bool(!1),ref:m.prop.json(void 0),required:m.prop.bool(!1),resize:m.prop.string(),rows:m.prop.json(void 0),value:m.prop.string(),variant:m.prop.string()},setup(t){let n=(0,m.useEmit)(),r=m.watchEffect,i=(0,m.inject)(f.FORM_CTX),a=f.useFormContext(t,i),p=(0,m.ref)(),g=s.createAutoResize({enabled:t[`auto-resize`]}),_=o.lifecycleSignal(m.onCleanup),v=l.createTextField({disabled:a.disabled,error:t.error,helper:t.helper,label:t.label,labelPlacement:t[`label-placement`],maxLength:t.maxlength,onChange:(e,t)=>{n(`change`,{originalEvent:e,value:t})},onInput:(e,t)=>{n(`input`,{originalEvent:e,value:t})},prefix:`textarea`,readonly:t.readonly,required:t.required,signal:_,validateOn:i?.validateOn,value:t.value});v.attachFormField(u.useField({disabled:v.disabled,onReset:()=>{v.reset(),requestAnimationFrame(()=>g.recompute())},toFormValue:e=>e,validationMessage:v.validationMessage,validity:v.validity,value:v.value}));let{ariaDescribedBy:y,ariaErrorMessage:b,ariaInvalid:x,ariaLabelledBy:S,assistiveId:C,counter:w,errorId:T,errorText:E,fieldId:D,helperText:O,labelId:k,labelVisible:A}=v;return(0,m.onElement)(p,e=>{let n=v.wire(e),i=g.wire(e);t.ref.value?.(e);let a=(0,h.watch)(t.ref,t=>{t?.(e)}),o=r(()=>{e.style.resize=t[`auto-resize`].value||t[`no-resize`].value?`none`:t.resize.value||`vertical`,requestAnimationFrame(()=>g.recompute())});return()=>{a.dispose(),t.ref.value?.(null),n(),i(),o()}}),(0,m.bind)({attr:{error:d.errorAttr(E),size:a.size,variant:a.variant}}),m.html`
|
|
2
2
|
<div class="textarea-wrapper" part="wrapper">
|
|
3
|
-
<label class="label" part="label" for="${
|
|
3
|
+
<label class="label" part="label" for="${D}" id="${k}" ?hidden="${()=>!A.value}"
|
|
4
4
|
>${t.label}</label
|
|
5
5
|
>
|
|
6
6
|
<div class="field" part="field">
|
|
7
7
|
<textarea
|
|
8
8
|
part="textarea"
|
|
9
|
-
ref="${
|
|
10
|
-
id="${
|
|
9
|
+
ref="${p}"
|
|
10
|
+
id="${D}"
|
|
11
11
|
:name="${t.name}"
|
|
12
12
|
:placeholder="${t.placeholder}"
|
|
13
13
|
:rows="${t.rows}"
|
|
@@ -15,19 +15,19 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
15
15
|
?disabled="${t.disabled}"
|
|
16
16
|
?readonly="${t.readonly}"
|
|
17
17
|
?required="${t.required}"
|
|
18
|
-
:value="${e.live(
|
|
19
|
-
:aria-describedby="${
|
|
20
|
-
:aria-errormessage="${
|
|
21
|
-
:aria-invalid="${
|
|
22
|
-
:aria-labelledby="${
|
|
18
|
+
:value="${e.live(v.value)}"
|
|
19
|
+
:aria-describedby="${y}"
|
|
20
|
+
:aria-errormessage="${b}"
|
|
21
|
+
:aria-invalid="${x}"
|
|
22
|
+
:aria-labelledby="${S}"></textarea>
|
|
23
23
|
</div>
|
|
24
|
-
<span class="${()=>
|
|
25
|
-
<div id="${
|
|
26
|
-
${()=>
|
|
24
|
+
<span class="${()=>c.counterClassName(w?.value)}" aria-live="polite" ?hidden="${()=>!w}">${()=>w?.value.counterText.replace(` / `,`/`)??``}</span>
|
|
25
|
+
<div id="${C}" class="helper-text" aria-live="polite" part="helper" ?hidden="${()=>!!E.value||!O.value}">
|
|
26
|
+
${()=>O.value}
|
|
27
27
|
</div>
|
|
28
|
-
<div id="${
|
|
29
|
-
${()=>
|
|
28
|
+
<div id="${T}" class="helper-text" role="alert" part="error" ?hidden="${()=>!E.value}">
|
|
29
|
+
${()=>E.value}
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
32
|
-
`},shadow:{delegatesFocus:!0},styles:[...r.fieldMixins,t.sizeVariantMixin(a.TEXTAREA_SIZE_PRESET),n.forcedColorsFocusMixin(`textarea`),
|
|
32
|
+
`},shadow:{delegatesFocus:!0},styles:[...r.fieldMixins,t.sizeVariantMixin(a.TEXTAREA_SIZE_PRESET),n.forcedColorsFocusMixin(`textarea`),p.default]}),exports.TEXTAREA_TAG=g;
|
|
33
33
|
//# sourceMappingURL=textarea.cjs.map
|
package/dist/textarea.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.cjs","names":[],"sources":["../src/inputs/textarea/textarea.ts"],"sourcesContent":["import { define, html, inject, prop, ref, bind, onCleanup, onElement, useEmit, watchEffect } from '@vielzeug/ore';\nimport { live } from '@vielzeug/ore/directives';\nimport { useField } from '@vielzeug/ore/forms';\nimport { watch as rippleWatch } from '@vielzeug/ripple';\n\nimport type { TextFieldProps } from '../../shared';\nimport type { VisualVariant } from '../../types';\n\nimport { lifecycleSignal, createTextField } from '../../headless';\nimport { disablableBundle, roundableBundle, sizableBundle, TEXTAREA_SIZE_PRESET, themableBundle } from '../../shared';\nimport { fieldMixins, forcedColorsFocusMixin, sizeVariantMixin } from '../../styles';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport componentStyles from './textarea.css?inline';\n\n/** Textarea component properties */\n\nexport type OreTextareaEvents = {\n change: { originalEvent: Event; value: string };\n input: { originalEvent: Event; value: string };\n};\n\nexport type OreTextareaProps = TextFieldProps<Exclude<VisualVariant, 'frost' | 'text'>> & {\n /** Allow auto-grow with content */\n 'auto-resize'?: boolean;\n /** Maximum character count; shows a counter when set */\n maxlength?: number;\n /** Disable a manual resize handle */\n 'no-resize'?: boolean;\n /**\n * JS-only callback fired with the inner `<textarea>` element when it mounts,\n * and with `null` when it unmounts. Intended for composed components that\n * need imperative access to the raw element.\n * Set as a JS property: `bitTextarea.ref = (el) => { ... }`.\n */\n ref?: ((el: HTMLTextAreaElement | null) => void) | null;\n /** Resize direction override */\n resize?: 'none' | 'horizontal' | 'both' | 'vertical';\n /** Number of visible text rows */\n rows?: number;\n};\n\n/**\n * A multi-line text input with label, helper text, character counter, and auto-resize.\n *\n * @element ore-textarea\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {string} value - Current value\n * @attr {string} placeholder - Placeholder text\n * @attr {string} name - Form field name\n * @attr {number} rows - Visible row count\n * @attr {number} maxlength - Max character count (shows counter)\n * @attr {string} helper - Helper text below the textarea\n * @attr {string} error - Error message\n * @attr {boolean} disabled - Disable interaction\n * @attr {boolean} readonly - Read-only mode\n * @attr {boolean} required - Required field\n * @attr {boolean} no-resize - Disable manual resize\n * @attr {boolean} auto-resize - Grow with content\n * @attr {string} resize - Resize direction: 'none' | 'horizontal' | 'both' | 'vertical'\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires input - Fired on every keystroke with current value. detail: { value: string; originalEvent: Event }\n * @fires change - Fired on blur with changed value. detail: { value: string; originalEvent: Event }\n *\n * @slot helper - Complex helper content\n *\n * @cssprop --textarea-bg - Background color\n * @cssprop --textarea-border-color - Border color\n * @cssprop --textarea-placeholder-color - Placeholder text color\n * @cssprop --textarea-radius - Border radius\n * @cssprop --textarea-padding - Inner padding (block inline)\n * @cssprop --textarea-gap - Gap between label and field\n * @cssprop --textarea-font-size - Font size\n * @cssprop --textarea-min-height - Minimum field height\n * @cssprop --textarea-max-height - Maximum field height (none = unlimited)\n * @cssprop --textarea-resize - CSS resize direction ('vertical' | 'horizontal' | 'both' | 'none')\n * @cssprop --textarea-hover-bg - Field background on hover (flat/ghost variants)\n * @cssprop --textarea-hover-border-color - Field border on hover (flat/bordered variants)\n * @cssprop --textarea-focus-bg - Field background when focused (flat variant)\n * @cssprop --textarea-focus-border-color - Field border when focused (flat variant)\n *\n * @part wrapper - Outer wrapper element.\n * @part label - Label element.\n * @part field - Field container.\n * @part textarea - The native `<textarea>` element.\n * @part helper - The helper text element.\n * @part error - The error text element (`role=\"alert\"`).\n *\n * @example\n * ```html\n * <ore-textarea></ore-textarea>\n * ```\n */\nexport const TEXTAREA_TAG = 'ore-textarea' as const;\ndefine<OreTextareaProps>(TEXTAREA_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n 'auto-resize': prop.bool(false),\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n maxlength: prop.json(undefined as number | undefined),\n name: prop.string(),\n 'no-resize': prop.bool(false),\n placeholder: prop.string(),\n readonly: prop.bool(false),\n ref: prop.json(undefined as ((el: HTMLTextAreaElement | null) => void) | null | undefined),\n required: prop.bool(false),\n resize: prop.string<'none' | 'both' | 'horizontal' | 'vertical'>(),\n rows: prop.json(undefined as number | undefined),\n value: prop.string(),\n variant: prop.string<'flat' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n setup(props) {\n const emit = useEmit<OreTextareaEvents>();\n const watch = watchEffect;\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n const textareaRef = ref<HTMLTextAreaElement>();\n\n const autoGrow = () => {\n if (!props['auto-resize'].value || !textareaRef.value) return;\n\n const textareaEl = textareaRef.value;\n\n textareaEl.style.height = 'auto';\n textareaEl.style.height = `${textareaEl.scrollHeight}px`;\n };\n\n const abortSignal = lifecycleSignal(onCleanup);\n let _formField: { reportValidity(): void } | null = null;\n const tf = createTextField({\n disabled: fCtxProps.disabled,\n error: props.error,\n getFormField: () => _formField,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n maxLength: props.maxlength,\n onBeforeInput: autoGrow,\n onChange: (event: Event, value: string) => {\n emit('change', { originalEvent: event, value });\n },\n onInput: (event: Event, value: string) => {\n emit('input', { originalEvent: event, value });\n },\n prefix: 'textarea',\n signal: abortSignal,\n validateOn: formCtx?.validateOn,\n value: props.value,\n });\n\n _formField = useField<string>({ disabled: tf.disabled, toFormValue: (v) => v, value: tf.value });\n\n const {\n ariaDescribedBy,\n ariaErrorMessage,\n ariaInvalid,\n ariaLabelledBy,\n assistiveId,\n counter,\n errorId,\n errorText,\n fieldId: textareaId,\n helperText,\n labelId,\n labelVisible,\n } = tf;\n\n onElement(textareaRef, (textareaEl) => {\n const unwireEl = tf.wire(textareaEl);\n\n props.ref.value?.(textareaEl);\n\n const sub = rippleWatch(props.ref, (cb) => {\n cb?.(textareaEl);\n });\n\n const stopLayoutEffect = watch(() => {\n textareaEl.style.resize =\n props['auto-resize'].value || props['no-resize'].value ? 'none' : props.resize.value || 'vertical';\n\n if (props['auto-resize'].value) {\n requestAnimationFrame(autoGrow);\n }\n });\n\n return () => {\n sub.dispose();\n props.ref.value?.(null);\n unwireEl();\n stopLayoutEffect();\n };\n });\n\n bind({\n attr: {\n error: () => errorText.value || undefined,\n size: fCtxProps.size,\n variant: fCtxProps.variant,\n },\n });\n\n const counterClass = () =>\n counter?.value.counterAtLimit\n ? 'counter at-limit'\n : counter?.value.counterNearLimit\n ? 'counter near-limit'\n : 'counter';\n const counterHidden = () => !counter;\n const counterText = () => counter?.value.counterText.replace(' / ', '/') ?? '';\n const helperHidden = () => !!errorText.value || !helperText.value;\n const errorHidden = () => !errorText.value;\n\n return html`\n <div class=\"textarea-wrapper\" part=\"wrapper\">\n <label class=\"label\" part=\"label\" for=\"${textareaId}\" id=\"${labelId}\" ?hidden=\"${() => !labelVisible.value}\"\n >${props.label}</label\n >\n <div class=\"field\" part=\"field\">\n <textarea\n part=\"textarea\"\n ref=\"${textareaRef}\"\n id=\"${textareaId}\"\n :name=\"${props.name}\"\n :placeholder=\"${props.placeholder}\"\n :rows=\"${props.rows}\"\n :maxlength=\"${props.maxlength}\"\n ?disabled=\"${props.disabled}\"\n ?readonly=\"${props.readonly}\"\n ?required=\"${props.required}\"\n :value=\"${live(tf.value)}\"\n :aria-describedby=\"${ariaDescribedBy}\"\n :aria-errormessage=\"${ariaErrorMessage}\"\n :aria-invalid=\"${ariaInvalid}\"\n :aria-labelledby=\"${ariaLabelledBy}\"></textarea>\n </div>\n <span class=\"${counterClass}\" aria-live=\"polite\" ?hidden=\"${counterHidden}\">${counterText}</span>\n <div id=\"${assistiveId}\" class=\"helper-text\" aria-live=\"polite\" part=\"helper\" ?hidden=\"${helperHidden}\">\n ${() => helperText.value}\n </div>\n <div id=\"${errorId}\" class=\"helper-text\" role=\"alert\" part=\"error\" ?hidden=\"${errorHidden}\">\n ${() => errorText.value}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [...fieldMixins, sizeVariantMixin(TEXTAREA_SIZE_PRESET), forcedColorsFocusMixin('textarea'), componentStyles],\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"textarea.cjs","names":[],"sources":["../src/inputs/textarea/textarea.ts"],"sourcesContent":["import { define, html, inject, prop, ref, bind, onCleanup, onElement, useEmit, watchEffect } from '@vielzeug/ore';\nimport { live } from '@vielzeug/ore/directives';\nimport { useField } from '@vielzeug/ore/forms';\nimport { watch as rippleWatch } from '@vielzeug/ripple';\n\nimport type { TextFieldProps } from '../../shared';\nimport type { VisualVariant } from '../../types';\n\nimport { counterClassName, createAutoResize, lifecycleSignal, createTextField } from '../../headless';\nimport { disablableBundle, roundableBundle, sizableBundle, TEXTAREA_SIZE_PRESET, themableBundle } from '../../shared';\nimport { fieldMixins, forcedColorsFocusMixin, sizeVariantMixin } from '../../styles';\nimport { errorAttr } from '../shared/field-binding';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport componentStyles from './textarea.css?inline';\n\n/** Textarea component properties */\n\nexport type OreTextareaEvents = {\n change: { originalEvent: Event; value: string };\n input: { originalEvent: Event; value: string };\n};\n\nexport type OreTextareaProps = TextFieldProps<Exclude<VisualVariant, 'frost' | 'text'>> & {\n /** Allow auto-grow with content */\n 'auto-resize'?: boolean;\n /** Maximum character count; shows a counter when set */\n maxlength?: number;\n /** Disable a manual resize handle */\n 'no-resize'?: boolean;\n /**\n * JS-only callback fired with the inner `<textarea>` element when it mounts,\n * and with `null` when it unmounts. Intended for composed components that\n * need imperative access to the raw element.\n * Set as a JS property: `bitTextarea.ref = (el) => { ... }`.\n */\n ref?: ((el: HTMLTextAreaElement | null) => void) | null;\n /** Resize direction override */\n resize?: 'none' | 'horizontal' | 'both' | 'vertical';\n /** Number of visible text rows */\n rows?: number;\n};\n\n/**\n * A multi-line text input with label, helper text, character counter, and auto-resize.\n *\n * @element ore-textarea\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {string} value - Current value\n * @attr {string} placeholder - Placeholder text\n * @attr {string} name - Form field name\n * @attr {number} rows - Visible row count\n * @attr {number} maxlength - Max character count (shows counter)\n * @attr {string} helper - Helper text below the textarea\n * @attr {string} error - Error message\n * @attr {boolean} disabled - Disable interaction\n * @attr {boolean} readonly - Read-only mode\n * @attr {boolean} required - Required field\n * @attr {boolean} no-resize - Disable manual resize\n * @attr {boolean} auto-resize - Grow with content\n * @attr {string} resize - Resize direction: 'none' | 'horizontal' | 'both' | 'vertical'\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires input - Fired on every keystroke with current value. detail: { value: string; originalEvent: Event }\n * @fires change - Fired on blur with changed value. detail: { value: string; originalEvent: Event }\n *\n * @slot helper - Complex helper content\n *\n * @cssprop --textarea-bg - Background color\n * @cssprop --textarea-border-color - Border color\n * @cssprop --textarea-placeholder-color - Placeholder text color\n * @cssprop --textarea-radius - Border radius\n * @cssprop --textarea-padding - Inner padding (block inline)\n * @cssprop --textarea-gap - Gap between label and field\n * @cssprop --textarea-font-size - Font size\n * @cssprop --textarea-min-height - Minimum field height\n * @cssprop --textarea-max-height - Maximum field height (none = unlimited)\n * @cssprop --textarea-resize - CSS resize direction ('vertical' | 'horizontal' | 'both' | 'none')\n * @cssprop --textarea-hover-bg - Field background on hover (flat/ghost variants)\n * @cssprop --textarea-hover-border-color - Field border on hover (flat/bordered variants)\n * @cssprop --textarea-focus-bg - Field background when focused (flat variant)\n * @cssprop --textarea-focus-border-color - Field border when focused (flat variant)\n *\n * @part wrapper - Outer wrapper element.\n * @part label - Label element.\n * @part field - Field container.\n * @part textarea - The native `<textarea>` element.\n * @part helper - The helper text element.\n * @part error - The error text element (`role=\"alert\"`).\n *\n * @example\n * ```html\n * <ore-textarea></ore-textarea>\n * ```\n */\nexport const TEXTAREA_TAG = 'ore-textarea' as const;\ndefine<OreTextareaProps>(TEXTAREA_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n 'auto-resize': prop.bool(false),\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n maxlength: prop.json(undefined as number | undefined),\n name: prop.string(),\n 'no-resize': prop.bool(false),\n placeholder: prop.string(),\n readonly: prop.bool(false),\n ref: prop.json(undefined as ((el: HTMLTextAreaElement | null) => void) | null | undefined),\n required: prop.bool(false),\n resize: prop.string<'none' | 'both' | 'horizontal' | 'vertical'>(),\n rows: prop.json(undefined as number | undefined),\n value: prop.string(),\n variant: prop.string<'flat' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n setup(props) {\n const emit = useEmit<OreTextareaEvents>();\n const watch = watchEffect;\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n const textareaRef = ref<HTMLTextAreaElement>();\n const autoResize = createAutoResize({ enabled: props['auto-resize'] });\n\n const abortSignal = lifecycleSignal(onCleanup);\n const tf = createTextField({\n disabled: fCtxProps.disabled,\n error: props.error,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n maxLength: props.maxlength,\n onChange: (event: Event, value: string) => {\n emit('change', { originalEvent: event, value });\n },\n onInput: (event: Event, value: string) => {\n emit('input', { originalEvent: event, value });\n },\n prefix: 'textarea',\n readonly: props.readonly,\n required: props.required,\n signal: abortSignal,\n validateOn: formCtx?.validateOn,\n value: props.value,\n });\n\n tf.attachFormField(\n useField<string>({\n disabled: tf.disabled,\n onReset: () => {\n tf.reset();\n requestAnimationFrame(() => autoResize.recompute());\n },\n toFormValue: (v) => v,\n validationMessage: tf.validationMessage,\n validity: tf.validity,\n value: tf.value,\n }),\n );\n\n const {\n ariaDescribedBy,\n ariaErrorMessage,\n ariaInvalid,\n ariaLabelledBy,\n assistiveId,\n counter,\n errorId,\n errorText,\n fieldId: textareaId,\n helperText,\n labelId,\n labelVisible,\n } = tf;\n\n onElement(textareaRef, (textareaEl) => {\n const unwireEl = tf.wire(textareaEl);\n const unwireAutoResize = autoResize.wire(textareaEl);\n\n props.ref.value?.(textareaEl);\n\n const sub = rippleWatch(props.ref, (cb) => {\n cb?.(textareaEl);\n });\n\n const stopLayoutEffect = watch(() => {\n textareaEl.style.resize =\n props['auto-resize'].value || props['no-resize'].value ? 'none' : props.resize.value || 'vertical';\n\n // Deferred a frame: on mount (or right after `auto-resize` flips true) the browser\n // hasn't necessarily finished laying out the textarea yet, so `scrollHeight` read\n // synchronously here could be stale.\n requestAnimationFrame(() => autoResize.recompute());\n });\n\n return () => {\n sub.dispose();\n props.ref.value?.(null);\n unwireEl();\n unwireAutoResize();\n stopLayoutEffect();\n };\n });\n\n bind({\n attr: {\n error: errorAttr(errorText),\n size: fCtxProps.size,\n variant: fCtxProps.variant,\n },\n });\n\n const counterClass = () => counterClassName(counter?.value);\n const counterHidden = () => !counter;\n const counterText = () => counter?.value.counterText.replace(' / ', '/') ?? '';\n const helperHidden = () => !!errorText.value || !helperText.value;\n const errorHidden = () => !errorText.value;\n\n return html`\n <div class=\"textarea-wrapper\" part=\"wrapper\">\n <label class=\"label\" part=\"label\" for=\"${textareaId}\" id=\"${labelId}\" ?hidden=\"${() => !labelVisible.value}\"\n >${props.label}</label\n >\n <div class=\"field\" part=\"field\">\n <textarea\n part=\"textarea\"\n ref=\"${textareaRef}\"\n id=\"${textareaId}\"\n :name=\"${props.name}\"\n :placeholder=\"${props.placeholder}\"\n :rows=\"${props.rows}\"\n :maxlength=\"${props.maxlength}\"\n ?disabled=\"${props.disabled}\"\n ?readonly=\"${props.readonly}\"\n ?required=\"${props.required}\"\n :value=\"${live(tf.value)}\"\n :aria-describedby=\"${ariaDescribedBy}\"\n :aria-errormessage=\"${ariaErrorMessage}\"\n :aria-invalid=\"${ariaInvalid}\"\n :aria-labelledby=\"${ariaLabelledBy}\"></textarea>\n </div>\n <span class=\"${counterClass}\" aria-live=\"polite\" ?hidden=\"${counterHidden}\">${counterText}</span>\n <div id=\"${assistiveId}\" class=\"helper-text\" aria-live=\"polite\" part=\"helper\" ?hidden=\"${helperHidden}\">\n ${() => helperText.value}\n </div>\n <div id=\"${errorId}\" class=\"helper-text\" role=\"alert\" part=\"error\" ?hidden=\"${errorHidden}\">\n ${() => errorText.value}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [...fieldMixins, sizeVariantMixin(TEXTAREA_SIZE_PRESET), forcedColorsFocusMixin('textarea'), componentStyles],\n});\n"],"mappings":"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"}
|
package/dist/textarea.js
CHANGED
|
@@ -6,54 +6,51 @@ import { fieldMixins as r } from "./styles/index.js";
|
|
|
6
6
|
import { disablableBundle as i, roundableBundle as a, sizableBundle as o, themableBundle as s } from "./shared/prop-bundles.js";
|
|
7
7
|
import { TEXTAREA_SIZE_PRESET as c } from "./shared/size-presets.js";
|
|
8
8
|
import { lifecycleSignal as l } from "./headless/ore.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { createAutoResize as u } from "./headless/auto-resize.js";
|
|
10
|
+
import { counterClassName as d } from "./headless/field-base.js";
|
|
11
|
+
import { createTextField as f } from "./headless/text-field.js";
|
|
12
|
+
import { useField as p } from "./ore/dist/forms/field.js";
|
|
11
13
|
import "./ore/dist/forms.js";
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
14
|
+
import { errorAttr as m } from "./inputs/shared/field-binding.js";
|
|
15
|
+
import { FORM_CTX as h, useFormContext as g } from "./inputs/shared/form-context.js";
|
|
16
|
+
import _ from "./inputs/textarea/textarea.css.js";
|
|
17
|
+
import { bind as v, define as y, html as b, inject as x, onCleanup as S, onElement as C, prop as w, ref as T, useEmit as E, watchEffect as D } from "@vielzeug/ore";
|
|
18
|
+
import { watch as O } from "@vielzeug/ripple";
|
|
16
19
|
//#region src/inputs/textarea/textarea.ts
|
|
17
|
-
var
|
|
18
|
-
|
|
20
|
+
var k = "ore-textarea";
|
|
21
|
+
y(k, {
|
|
19
22
|
formAssociated: !0,
|
|
20
23
|
props: {
|
|
21
24
|
...s,
|
|
22
25
|
...o,
|
|
23
26
|
...i,
|
|
24
27
|
...a,
|
|
25
|
-
"auto-resize":
|
|
26
|
-
error:
|
|
27
|
-
fullwidth:
|
|
28
|
-
helper:
|
|
29
|
-
label:
|
|
30
|
-
"label-placement":
|
|
31
|
-
maxlength:
|
|
32
|
-
name:
|
|
33
|
-
"no-resize":
|
|
34
|
-
placeholder:
|
|
35
|
-
readonly:
|
|
36
|
-
ref:
|
|
37
|
-
required:
|
|
38
|
-
resize:
|
|
39
|
-
rows:
|
|
40
|
-
value:
|
|
41
|
-
variant:
|
|
28
|
+
"auto-resize": w.bool(!1),
|
|
29
|
+
error: w.string(),
|
|
30
|
+
fullwidth: w.bool(!1),
|
|
31
|
+
helper: w.string(),
|
|
32
|
+
label: w.string(),
|
|
33
|
+
"label-placement": w.oneOf(["inset", "outside"], "inset"),
|
|
34
|
+
maxlength: w.json(void 0),
|
|
35
|
+
name: w.string(),
|
|
36
|
+
"no-resize": w.bool(!1),
|
|
37
|
+
placeholder: w.string(),
|
|
38
|
+
readonly: w.bool(!1),
|
|
39
|
+
ref: w.json(void 0),
|
|
40
|
+
required: w.bool(!1),
|
|
41
|
+
resize: w.string(),
|
|
42
|
+
rows: w.json(void 0),
|
|
43
|
+
value: w.string(),
|
|
44
|
+
variant: w.string()
|
|
42
45
|
},
|
|
43
46
|
setup(t) {
|
|
44
|
-
let n =
|
|
45
|
-
if (!t["auto-resize"].value || !o.value) return;
|
|
46
|
-
let e = o.value;
|
|
47
|
-
e.style.height = "auto", e.style.height = `${e.scrollHeight}px`;
|
|
48
|
-
}, c = l(y), m = null, g = u({
|
|
47
|
+
let n = E(), r = D, i = x(h), a = g(t, i), o = T(), s = u({ enabled: t["auto-resize"] }), c = l(S), _ = f({
|
|
49
48
|
disabled: a.disabled,
|
|
50
49
|
error: t.error,
|
|
51
|
-
getFormField: () => m,
|
|
52
50
|
helper: t.helper,
|
|
53
51
|
label: t.label,
|
|
54
52
|
labelPlacement: t["label-placement"],
|
|
55
53
|
maxLength: t.maxlength,
|
|
56
|
-
onBeforeInput: s,
|
|
57
54
|
onChange: (e, t) => {
|
|
58
55
|
n("change", {
|
|
59
56
|
originalEvent: e,
|
|
@@ -67,41 +64,48 @@ g(E, {
|
|
|
67
64
|
});
|
|
68
65
|
},
|
|
69
66
|
prefix: "textarea",
|
|
67
|
+
readonly: t.readonly,
|
|
68
|
+
required: t.required,
|
|
70
69
|
signal: c,
|
|
71
70
|
validateOn: i?.validateOn,
|
|
72
71
|
value: t.value
|
|
73
72
|
});
|
|
74
|
-
|
|
75
|
-
disabled:
|
|
73
|
+
_.attachFormField(p({
|
|
74
|
+
disabled: _.disabled,
|
|
75
|
+
onReset: () => {
|
|
76
|
+
_.reset(), requestAnimationFrame(() => s.recompute());
|
|
77
|
+
},
|
|
76
78
|
toFormValue: (e) => e,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
validationMessage: _.validationMessage,
|
|
80
|
+
validity: _.validity,
|
|
81
|
+
value: _.value
|
|
82
|
+
}));
|
|
83
|
+
let { ariaDescribedBy: y, ariaErrorMessage: w, ariaInvalid: k, ariaLabelledBy: A, assistiveId: j, counter: M, errorId: N, errorText: P, fieldId: F, helperText: I, labelId: L, labelVisible: R } = _;
|
|
84
|
+
return C(o, (e) => {
|
|
85
|
+
let n = _.wire(e), i = s.wire(e);
|
|
82
86
|
t.ref.value?.(e);
|
|
83
|
-
let
|
|
87
|
+
let a = O(t.ref, (t) => {
|
|
84
88
|
t?.(e);
|
|
85
|
-
}),
|
|
86
|
-
e.style.resize = t["auto-resize"].value || t["no-resize"].value ? "none" : t.resize.value || "vertical",
|
|
89
|
+
}), o = r(() => {
|
|
90
|
+
e.style.resize = t["auto-resize"].value || t["no-resize"].value ? "none" : t.resize.value || "vertical", requestAnimationFrame(() => s.recompute());
|
|
87
91
|
});
|
|
88
92
|
return () => {
|
|
89
|
-
|
|
93
|
+
a.dispose(), t.ref.value?.(null), n(), i(), o();
|
|
90
94
|
};
|
|
91
|
-
}),
|
|
92
|
-
error: ()
|
|
95
|
+
}), v({ attr: {
|
|
96
|
+
error: m(P),
|
|
93
97
|
size: a.size,
|
|
94
98
|
variant: a.variant
|
|
95
|
-
} }),
|
|
99
|
+
} }), b`
|
|
96
100
|
<div class="textarea-wrapper" part="wrapper">
|
|
97
|
-
<label class="label" part="label" for="${
|
|
101
|
+
<label class="label" part="label" for="${F}" id="${L}" ?hidden="${() => !R.value}"
|
|
98
102
|
>${t.label}</label
|
|
99
103
|
>
|
|
100
104
|
<div class="field" part="field">
|
|
101
105
|
<textarea
|
|
102
106
|
part="textarea"
|
|
103
107
|
ref="${o}"
|
|
104
|
-
id="${
|
|
108
|
+
id="${F}"
|
|
105
109
|
:name="${t.name}"
|
|
106
110
|
:placeholder="${t.placeholder}"
|
|
107
111
|
:rows="${t.rows}"
|
|
@@ -109,18 +113,18 @@ g(E, {
|
|
|
109
113
|
?disabled="${t.disabled}"
|
|
110
114
|
?readonly="${t.readonly}"
|
|
111
115
|
?required="${t.required}"
|
|
112
|
-
:value="${e(
|
|
113
|
-
:aria-describedby="${
|
|
114
|
-
:aria-errormessage="${
|
|
115
|
-
:aria-invalid="${
|
|
116
|
-
:aria-labelledby="${
|
|
116
|
+
:value="${e(_.value)}"
|
|
117
|
+
:aria-describedby="${y}"
|
|
118
|
+
:aria-errormessage="${w}"
|
|
119
|
+
:aria-invalid="${k}"
|
|
120
|
+
:aria-labelledby="${A}"></textarea>
|
|
117
121
|
</div>
|
|
118
|
-
<span class="${() =>
|
|
119
|
-
<div id="${
|
|
120
|
-
${() =>
|
|
122
|
+
<span class="${() => d(M?.value)}" aria-live="polite" ?hidden="${() => !M}">${() => M?.value.counterText.replace(" / ", "/") ?? ""}</span>
|
|
123
|
+
<div id="${j}" class="helper-text" aria-live="polite" part="helper" ?hidden="${() => !!P.value || !I.value}">
|
|
124
|
+
${() => I.value}
|
|
121
125
|
</div>
|
|
122
|
-
<div id="${
|
|
123
|
-
${() =>
|
|
126
|
+
<div id="${N}" class="helper-text" role="alert" part="error" ?hidden="${() => !P.value}">
|
|
127
|
+
${() => P.value}
|
|
124
128
|
</div>
|
|
125
129
|
</div>
|
|
126
130
|
`;
|
|
@@ -130,10 +134,10 @@ g(E, {
|
|
|
130
134
|
...r,
|
|
131
135
|
t(c),
|
|
132
136
|
n("textarea"),
|
|
133
|
-
|
|
137
|
+
_
|
|
134
138
|
]
|
|
135
139
|
});
|
|
136
140
|
//#endregion
|
|
137
|
-
export {
|
|
141
|
+
export { k as TEXTAREA_TAG };
|
|
138
142
|
|
|
139
143
|
//# sourceMappingURL=textarea.js.map
|
package/dist/textarea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.js","names":[],"sources":["../src/inputs/textarea/textarea.ts"],"sourcesContent":["import { define, html, inject, prop, ref, bind, onCleanup, onElement, useEmit, watchEffect } from '@vielzeug/ore';\nimport { live } from '@vielzeug/ore/directives';\nimport { useField } from '@vielzeug/ore/forms';\nimport { watch as rippleWatch } from '@vielzeug/ripple';\n\nimport type { TextFieldProps } from '../../shared';\nimport type { VisualVariant } from '../../types';\n\nimport { lifecycleSignal, createTextField } from '../../headless';\nimport { disablableBundle, roundableBundle, sizableBundle, TEXTAREA_SIZE_PRESET, themableBundle } from '../../shared';\nimport { fieldMixins, forcedColorsFocusMixin, sizeVariantMixin } from '../../styles';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport componentStyles from './textarea.css?inline';\n\n/** Textarea component properties */\n\nexport type OreTextareaEvents = {\n change: { originalEvent: Event; value: string };\n input: { originalEvent: Event; value: string };\n};\n\nexport type OreTextareaProps = TextFieldProps<Exclude<VisualVariant, 'frost' | 'text'>> & {\n /** Allow auto-grow with content */\n 'auto-resize'?: boolean;\n /** Maximum character count; shows a counter when set */\n maxlength?: number;\n /** Disable a manual resize handle */\n 'no-resize'?: boolean;\n /**\n * JS-only callback fired with the inner `<textarea>` element when it mounts,\n * and with `null` when it unmounts. Intended for composed components that\n * need imperative access to the raw element.\n * Set as a JS property: `bitTextarea.ref = (el) => { ... }`.\n */\n ref?: ((el: HTMLTextAreaElement | null) => void) | null;\n /** Resize direction override */\n resize?: 'none' | 'horizontal' | 'both' | 'vertical';\n /** Number of visible text rows */\n rows?: number;\n};\n\n/**\n * A multi-line text input with label, helper text, character counter, and auto-resize.\n *\n * @element ore-textarea\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {string} value - Current value\n * @attr {string} placeholder - Placeholder text\n * @attr {string} name - Form field name\n * @attr {number} rows - Visible row count\n * @attr {number} maxlength - Max character count (shows counter)\n * @attr {string} helper - Helper text below the textarea\n * @attr {string} error - Error message\n * @attr {boolean} disabled - Disable interaction\n * @attr {boolean} readonly - Read-only mode\n * @attr {boolean} required - Required field\n * @attr {boolean} no-resize - Disable manual resize\n * @attr {boolean} auto-resize - Grow with content\n * @attr {string} resize - Resize direction: 'none' | 'horizontal' | 'both' | 'vertical'\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires input - Fired on every keystroke with current value. detail: { value: string; originalEvent: Event }\n * @fires change - Fired on blur with changed value. detail: { value: string; originalEvent: Event }\n *\n * @slot helper - Complex helper content\n *\n * @cssprop --textarea-bg - Background color\n * @cssprop --textarea-border-color - Border color\n * @cssprop --textarea-placeholder-color - Placeholder text color\n * @cssprop --textarea-radius - Border radius\n * @cssprop --textarea-padding - Inner padding (block inline)\n * @cssprop --textarea-gap - Gap between label and field\n * @cssprop --textarea-font-size - Font size\n * @cssprop --textarea-min-height - Minimum field height\n * @cssprop --textarea-max-height - Maximum field height (none = unlimited)\n * @cssprop --textarea-resize - CSS resize direction ('vertical' | 'horizontal' | 'both' | 'none')\n * @cssprop --textarea-hover-bg - Field background on hover (flat/ghost variants)\n * @cssprop --textarea-hover-border-color - Field border on hover (flat/bordered variants)\n * @cssprop --textarea-focus-bg - Field background when focused (flat variant)\n * @cssprop --textarea-focus-border-color - Field border when focused (flat variant)\n *\n * @part wrapper - Outer wrapper element.\n * @part label - Label element.\n * @part field - Field container.\n * @part textarea - The native `<textarea>` element.\n * @part helper - The helper text element.\n * @part error - The error text element (`role=\"alert\"`).\n *\n * @example\n * ```html\n * <ore-textarea></ore-textarea>\n * ```\n */\nexport const TEXTAREA_TAG = 'ore-textarea' as const;\ndefine<OreTextareaProps>(TEXTAREA_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n 'auto-resize': prop.bool(false),\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n maxlength: prop.json(undefined as number | undefined),\n name: prop.string(),\n 'no-resize': prop.bool(false),\n placeholder: prop.string(),\n readonly: prop.bool(false),\n ref: prop.json(undefined as ((el: HTMLTextAreaElement | null) => void) | null | undefined),\n required: prop.bool(false),\n resize: prop.string<'none' | 'both' | 'horizontal' | 'vertical'>(),\n rows: prop.json(undefined as number | undefined),\n value: prop.string(),\n variant: prop.string<'flat' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n setup(props) {\n const emit = useEmit<OreTextareaEvents>();\n const watch = watchEffect;\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n const textareaRef = ref<HTMLTextAreaElement>();\n\n const autoGrow = () => {\n if (!props['auto-resize'].value || !textareaRef.value) return;\n\n const textareaEl = textareaRef.value;\n\n textareaEl.style.height = 'auto';\n textareaEl.style.height = `${textareaEl.scrollHeight}px`;\n };\n\n const abortSignal = lifecycleSignal(onCleanup);\n let _formField: { reportValidity(): void } | null = null;\n const tf = createTextField({\n disabled: fCtxProps.disabled,\n error: props.error,\n getFormField: () => _formField,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n maxLength: props.maxlength,\n onBeforeInput: autoGrow,\n onChange: (event: Event, value: string) => {\n emit('change', { originalEvent: event, value });\n },\n onInput: (event: Event, value: string) => {\n emit('input', { originalEvent: event, value });\n },\n prefix: 'textarea',\n signal: abortSignal,\n validateOn: formCtx?.validateOn,\n value: props.value,\n });\n\n _formField = useField<string>({ disabled: tf.disabled, toFormValue: (v) => v, value: tf.value });\n\n const {\n ariaDescribedBy,\n ariaErrorMessage,\n ariaInvalid,\n ariaLabelledBy,\n assistiveId,\n counter,\n errorId,\n errorText,\n fieldId: textareaId,\n helperText,\n labelId,\n labelVisible,\n } = tf;\n\n onElement(textareaRef, (textareaEl) => {\n const unwireEl = tf.wire(textareaEl);\n\n props.ref.value?.(textareaEl);\n\n const sub = rippleWatch(props.ref, (cb) => {\n cb?.(textareaEl);\n });\n\n const stopLayoutEffect = watch(() => {\n textareaEl.style.resize =\n props['auto-resize'].value || props['no-resize'].value ? 'none' : props.resize.value || 'vertical';\n\n if (props['auto-resize'].value) {\n requestAnimationFrame(autoGrow);\n }\n });\n\n return () => {\n sub.dispose();\n props.ref.value?.(null);\n unwireEl();\n stopLayoutEffect();\n };\n });\n\n bind({\n attr: {\n error: () => errorText.value || undefined,\n size: fCtxProps.size,\n variant: fCtxProps.variant,\n },\n });\n\n const counterClass = () =>\n counter?.value.counterAtLimit\n ? 'counter at-limit'\n : counter?.value.counterNearLimit\n ? 'counter near-limit'\n : 'counter';\n const counterHidden = () => !counter;\n const counterText = () => counter?.value.counterText.replace(' / ', '/') ?? '';\n const helperHidden = () => !!errorText.value || !helperText.value;\n const errorHidden = () => !errorText.value;\n\n return html`\n <div class=\"textarea-wrapper\" part=\"wrapper\">\n <label class=\"label\" part=\"label\" for=\"${textareaId}\" id=\"${labelId}\" ?hidden=\"${() => !labelVisible.value}\"\n >${props.label}</label\n >\n <div class=\"field\" part=\"field\">\n <textarea\n part=\"textarea\"\n ref=\"${textareaRef}\"\n id=\"${textareaId}\"\n :name=\"${props.name}\"\n :placeholder=\"${props.placeholder}\"\n :rows=\"${props.rows}\"\n :maxlength=\"${props.maxlength}\"\n ?disabled=\"${props.disabled}\"\n ?readonly=\"${props.readonly}\"\n ?required=\"${props.required}\"\n :value=\"${live(tf.value)}\"\n :aria-describedby=\"${ariaDescribedBy}\"\n :aria-errormessage=\"${ariaErrorMessage}\"\n :aria-invalid=\"${ariaInvalid}\"\n :aria-labelledby=\"${ariaLabelledBy}\"></textarea>\n </div>\n <span class=\"${counterClass}\" aria-live=\"polite\" ?hidden=\"${counterHidden}\">${counterText}</span>\n <div id=\"${assistiveId}\" class=\"helper-text\" aria-live=\"polite\" part=\"helper\" ?hidden=\"${helperHidden}\">\n ${() => helperText.value}\n </div>\n <div id=\"${errorId}\" class=\"helper-text\" role=\"alert\" part=\"error\" ?hidden=\"${errorHidden}\">\n ${() => errorText.value}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [...fieldMixins, sizeVariantMixin(TEXTAREA_SIZE_PRESET), forcedColorsFocusMixin('textarea'), componentStyles],\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"textarea.js","names":[],"sources":["../src/inputs/textarea/textarea.ts"],"sourcesContent":["import { define, html, inject, prop, ref, bind, onCleanup, onElement, useEmit, watchEffect } from '@vielzeug/ore';\nimport { live } from '@vielzeug/ore/directives';\nimport { useField } from '@vielzeug/ore/forms';\nimport { watch as rippleWatch } from '@vielzeug/ripple';\n\nimport type { TextFieldProps } from '../../shared';\nimport type { VisualVariant } from '../../types';\n\nimport { counterClassName, createAutoResize, lifecycleSignal, createTextField } from '../../headless';\nimport { disablableBundle, roundableBundle, sizableBundle, TEXTAREA_SIZE_PRESET, themableBundle } from '../../shared';\nimport { fieldMixins, forcedColorsFocusMixin, sizeVariantMixin } from '../../styles';\nimport { errorAttr } from '../shared/field-binding';\nimport { FORM_CTX, useFormContext } from '../shared/form-context';\nimport componentStyles from './textarea.css?inline';\n\n/** Textarea component properties */\n\nexport type OreTextareaEvents = {\n change: { originalEvent: Event; value: string };\n input: { originalEvent: Event; value: string };\n};\n\nexport type OreTextareaProps = TextFieldProps<Exclude<VisualVariant, 'frost' | 'text'>> & {\n /** Allow auto-grow with content */\n 'auto-resize'?: boolean;\n /** Maximum character count; shows a counter when set */\n maxlength?: number;\n /** Disable a manual resize handle */\n 'no-resize'?: boolean;\n /**\n * JS-only callback fired with the inner `<textarea>` element when it mounts,\n * and with `null` when it unmounts. Intended for composed components that\n * need imperative access to the raw element.\n * Set as a JS property: `bitTextarea.ref = (el) => { ... }`.\n */\n ref?: ((el: HTMLTextAreaElement | null) => void) | null;\n /** Resize direction override */\n resize?: 'none' | 'horizontal' | 'both' | 'vertical';\n /** Number of visible text rows */\n rows?: number;\n};\n\n/**\n * A multi-line text input with label, helper text, character counter, and auto-resize.\n *\n * @element ore-textarea\n *\n * @attr {string} label - Label text\n * @attr {string} label-placement - 'inset' | 'outside'\n * @attr {string} value - Current value\n * @attr {string} placeholder - Placeholder text\n * @attr {string} name - Form field name\n * @attr {number} rows - Visible row count\n * @attr {number} maxlength - Max character count (shows counter)\n * @attr {string} helper - Helper text below the textarea\n * @attr {string} error - Error message\n * @attr {boolean} disabled - Disable interaction\n * @attr {boolean} readonly - Read-only mode\n * @attr {boolean} required - Required field\n * @attr {boolean} no-resize - Disable manual resize\n * @attr {boolean} auto-resize - Grow with content\n * @attr {string} resize - Resize direction: 'none' | 'horizontal' | 'both' | 'vertical'\n * @attr {string} color - Theme color: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n * @attr {string} variant - Visual variant: 'solid' | 'flat' | 'bordered' | 'outline' | 'ghost'\n * @attr {string} size - Component size: 'sm' | 'md' | 'lg'\n * @attr {string} rounded - Border radius: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n *\n * @fires input - Fired on every keystroke with current value. detail: { value: string; originalEvent: Event }\n * @fires change - Fired on blur with changed value. detail: { value: string; originalEvent: Event }\n *\n * @slot helper - Complex helper content\n *\n * @cssprop --textarea-bg - Background color\n * @cssprop --textarea-border-color - Border color\n * @cssprop --textarea-placeholder-color - Placeholder text color\n * @cssprop --textarea-radius - Border radius\n * @cssprop --textarea-padding - Inner padding (block inline)\n * @cssprop --textarea-gap - Gap between label and field\n * @cssprop --textarea-font-size - Font size\n * @cssprop --textarea-min-height - Minimum field height\n * @cssprop --textarea-max-height - Maximum field height (none = unlimited)\n * @cssprop --textarea-resize - CSS resize direction ('vertical' | 'horizontal' | 'both' | 'none')\n * @cssprop --textarea-hover-bg - Field background on hover (flat/ghost variants)\n * @cssprop --textarea-hover-border-color - Field border on hover (flat/bordered variants)\n * @cssprop --textarea-focus-bg - Field background when focused (flat variant)\n * @cssprop --textarea-focus-border-color - Field border when focused (flat variant)\n *\n * @part wrapper - Outer wrapper element.\n * @part label - Label element.\n * @part field - Field container.\n * @part textarea - The native `<textarea>` element.\n * @part helper - The helper text element.\n * @part error - The error text element (`role=\"alert\"`).\n *\n * @example\n * ```html\n * <ore-textarea></ore-textarea>\n * ```\n */\nexport const TEXTAREA_TAG = 'ore-textarea' as const;\ndefine<OreTextareaProps>(TEXTAREA_TAG, {\n formAssociated: true,\n props: {\n ...themableBundle,\n ...sizableBundle,\n ...disablableBundle,\n ...roundableBundle,\n 'auto-resize': prop.bool(false),\n error: prop.string(),\n fullwidth: prop.bool(false),\n helper: prop.string(),\n label: prop.string(),\n 'label-placement': prop.oneOf(['inset', 'outside'] as const, 'inset'),\n maxlength: prop.json(undefined as number | undefined),\n name: prop.string(),\n 'no-resize': prop.bool(false),\n placeholder: prop.string(),\n readonly: prop.bool(false),\n ref: prop.json(undefined as ((el: HTMLTextAreaElement | null) => void) | null | undefined),\n required: prop.bool(false),\n resize: prop.string<'none' | 'both' | 'horizontal' | 'vertical'>(),\n rows: prop.json(undefined as number | undefined),\n value: prop.string(),\n variant: prop.string<'flat' | 'solid' | 'bordered' | 'outline' | 'ghost'>(),\n },\n setup(props) {\n const emit = useEmit<OreTextareaEvents>();\n const watch = watchEffect;\n\n const formCtx = inject(FORM_CTX);\n const fCtxProps = useFormContext(props, formCtx);\n\n const textareaRef = ref<HTMLTextAreaElement>();\n const autoResize = createAutoResize({ enabled: props['auto-resize'] });\n\n const abortSignal = lifecycleSignal(onCleanup);\n const tf = createTextField({\n disabled: fCtxProps.disabled,\n error: props.error,\n helper: props.helper,\n label: props.label,\n labelPlacement: props['label-placement'],\n maxLength: props.maxlength,\n onChange: (event: Event, value: string) => {\n emit('change', { originalEvent: event, value });\n },\n onInput: (event: Event, value: string) => {\n emit('input', { originalEvent: event, value });\n },\n prefix: 'textarea',\n readonly: props.readonly,\n required: props.required,\n signal: abortSignal,\n validateOn: formCtx?.validateOn,\n value: props.value,\n });\n\n tf.attachFormField(\n useField<string>({\n disabled: tf.disabled,\n onReset: () => {\n tf.reset();\n requestAnimationFrame(() => autoResize.recompute());\n },\n toFormValue: (v) => v,\n validationMessage: tf.validationMessage,\n validity: tf.validity,\n value: tf.value,\n }),\n );\n\n const {\n ariaDescribedBy,\n ariaErrorMessage,\n ariaInvalid,\n ariaLabelledBy,\n assistiveId,\n counter,\n errorId,\n errorText,\n fieldId: textareaId,\n helperText,\n labelId,\n labelVisible,\n } = tf;\n\n onElement(textareaRef, (textareaEl) => {\n const unwireEl = tf.wire(textareaEl);\n const unwireAutoResize = autoResize.wire(textareaEl);\n\n props.ref.value?.(textareaEl);\n\n const sub = rippleWatch(props.ref, (cb) => {\n cb?.(textareaEl);\n });\n\n const stopLayoutEffect = watch(() => {\n textareaEl.style.resize =\n props['auto-resize'].value || props['no-resize'].value ? 'none' : props.resize.value || 'vertical';\n\n // Deferred a frame: on mount (or right after `auto-resize` flips true) the browser\n // hasn't necessarily finished laying out the textarea yet, so `scrollHeight` read\n // synchronously here could be stale.\n requestAnimationFrame(() => autoResize.recompute());\n });\n\n return () => {\n sub.dispose();\n props.ref.value?.(null);\n unwireEl();\n unwireAutoResize();\n stopLayoutEffect();\n };\n });\n\n bind({\n attr: {\n error: errorAttr(errorText),\n size: fCtxProps.size,\n variant: fCtxProps.variant,\n },\n });\n\n const counterClass = () => counterClassName(counter?.value);\n const counterHidden = () => !counter;\n const counterText = () => counter?.value.counterText.replace(' / ', '/') ?? '';\n const helperHidden = () => !!errorText.value || !helperText.value;\n const errorHidden = () => !errorText.value;\n\n return html`\n <div class=\"textarea-wrapper\" part=\"wrapper\">\n <label class=\"label\" part=\"label\" for=\"${textareaId}\" id=\"${labelId}\" ?hidden=\"${() => !labelVisible.value}\"\n >${props.label}</label\n >\n <div class=\"field\" part=\"field\">\n <textarea\n part=\"textarea\"\n ref=\"${textareaRef}\"\n id=\"${textareaId}\"\n :name=\"${props.name}\"\n :placeholder=\"${props.placeholder}\"\n :rows=\"${props.rows}\"\n :maxlength=\"${props.maxlength}\"\n ?disabled=\"${props.disabled}\"\n ?readonly=\"${props.readonly}\"\n ?required=\"${props.required}\"\n :value=\"${live(tf.value)}\"\n :aria-describedby=\"${ariaDescribedBy}\"\n :aria-errormessage=\"${ariaErrorMessage}\"\n :aria-invalid=\"${ariaInvalid}\"\n :aria-labelledby=\"${ariaLabelledBy}\"></textarea>\n </div>\n <span class=\"${counterClass}\" aria-live=\"polite\" ?hidden=\"${counterHidden}\">${counterText}</span>\n <div id=\"${assistiveId}\" class=\"helper-text\" aria-live=\"polite\" part=\"helper\" ?hidden=\"${helperHidden}\">\n ${() => helperText.value}\n </div>\n <div id=\"${errorId}\" class=\"helper-text\" role=\"alert\" part=\"error\" ?hidden=\"${errorHidden}\">\n ${() => errorText.value}\n </div>\n </div>\n `;\n },\n shadow: { delegatesFocus: true },\n styles: [...fieldMixins, sizeVariantMixin(TEXTAREA_SIZE_PRESET), forcedColorsFocusMixin('textarea'), componentStyles],\n});\n"],"mappings":"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"}
|