@plexui/vue 0.1.9 → 0.1.11
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/es/components/Field/Field.js +8 -3
- package/dist/es/components/Field/Field.js.map +1 -1
- package/dist/es/components/FieldGroup/FieldGroup.js +54 -0
- package/dist/es/components/FieldGroup/FieldGroup.js.map +1 -0
- package/dist/es/components/FieldGroup/index.js +2 -0
- package/dist/es/components/FieldGroup/index.js.map +1 -0
- package/dist/es/components/FloatingLabelInput/FloatingLabelInput.js +10 -1
- package/dist/es/components/FloatingLabelInput/FloatingLabelInput.js.map +1 -1
- package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.js +10 -1
- package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.js.map +1 -1
- package/dist/types/components/Field/Field.d.ts +13 -9
- package/dist/types/components/FieldGroup/FieldGroup.d.ts +40 -0
- package/dist/types/components/FieldGroup/index.d.ts +1 -0
- package/dist/types/components/FloatingLabelInput/FloatingLabelInput.d.ts +22 -0
- package/dist/types/components/FloatingLabelSelect/FloatingLabelSelect.d.ts +22 -0
- package/package.json +1 -1
|
@@ -112,8 +112,10 @@ const FieldComponent = defineComponent({
|
|
|
112
112
|
size: String,
|
|
113
113
|
/** Shows a required asterisk after the label. Visual only: no `required` attribute. @default false */
|
|
114
114
|
required: { type: Boolean, default: false },
|
|
115
|
-
/** Layout direction of label and control. @default "vertical" */
|
|
116
|
-
orientation:
|
|
115
|
+
/** Layout direction of label and control. @default "horizontal" on a `row`, else "vertical" */
|
|
116
|
+
orientation: String,
|
|
117
|
+
/** One line of a FieldGroup: label at the start, control at the end. @default false */
|
|
118
|
+
row: { type: Boolean, default: false },
|
|
117
119
|
/** Overrides the generated id set on the control and the label's `for`. A child's own `id` wins over both. */
|
|
118
120
|
id: String,
|
|
119
121
|
/** Optically aligns the control's text with surrounding content; passed to the control. */
|
|
@@ -123,7 +125,8 @@ const FieldComponent = defineComponent({
|
|
|
123
125
|
setup(props, { attrs, slots }) {
|
|
124
126
|
const generatedId = useId();
|
|
125
127
|
return () => {
|
|
126
|
-
const { required,
|
|
128
|
+
const { required, row, opticallyAlign } = props;
|
|
129
|
+
const orientation = props.orientation ?? (row ? "horizontal" : "vertical");
|
|
127
130
|
const fieldId = props.id || `field-${generatedId}`;
|
|
128
131
|
const labelId = `${fieldId}-label`;
|
|
129
132
|
const description = slots.description ? slots.description() : props.description;
|
|
@@ -163,10 +166,12 @@ const FieldComponent = defineComponent({
|
|
|
163
166
|
required ? h("span", { "class": s.RequiredIndicator, "aria-hidden": "true" }, "*") : null,
|
|
164
167
|
]);
|
|
165
168
|
return h("div", {
|
|
169
|
+
...(row && attrs),
|
|
166
170
|
"class": clsx(s.Field, attrs.class),
|
|
167
171
|
"data-size": size,
|
|
168
172
|
"data-orientation": orientation,
|
|
169
173
|
"data-optically-align": opticallyAlign,
|
|
174
|
+
"data-row": row ? "" : undefined,
|
|
170
175
|
}, [
|
|
171
176
|
h("div", { class: s.LabelGroup }, [
|
|
172
177
|
hasLabelAction
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.js","sourceRoot":"","sources":["../../../../src/components/Field/Field.ts"],"names":[],"mappings":"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","sourcesContent":["import clsx, { type ClassValue } from \"clsx\"\nimport {\n Comment,\n Fragment,\n Static,\n Text,\n camelize,\n cloneVNode,\n defineComponent,\n h,\n isVNode,\n useId,\n type PropType,\n type SlotsType,\n type VNode,\n type VNodeArrayChildren,\n type VNodeChild,\n} from \"vue\"\nimport type { ControlSize } from \"@plexui/styles/types\"\nimport { FieldError } from \"../FieldError/index.js\"\nimport { hasContent } from \"../../lib/slotContent.js\"\nimport s from \"@plexui/styles/components/Field/Field.module.css\"\n\n// Vue port of packages/ui/src/components/Field/Field.tsx.\n//\n// - `label`, `description` and `errorMessage` take a string prop or a slot of\n// the same name (the slot wins), like React's ReactNode props.\n// - Children: React accepts an element, which Field clones with the field\n// props, or a render prop `(fieldProps) => ReactNode`, which it leaves alone.\n// Both are the default slot here, which receives the field props:\n// - a slot that reads them (`v-slot=\"fieldProps\"` + `v-bind=\"fieldProps\"`,\n// `v-slot=\"{ id }\"`, `(fieldProps) => h(...)`) is the render prop: its\n// content renders as it is.\n// - a slot that does not read them and holds exactly one element or\n// component gets it cloned like React's `cloneElement`: `opticallyAlign`\n// replaces the child's own, the child's own `id` stays and the label's\n// `for` follows it, `aria-describedby` is joined after the child's own\n// ids, and an explicit `aria-invalid` on the child wins. Template\n// comments do not count as children (JSX comments); the\n// placeholder of a `v-if` that renders nothing does, like `{false}` in a\n// React children array, so `<A v-if=\"x\" /><Input />` is not cloned.\n// - anything else (text, several roots, a `v-for` list) renders as it is,\n// like a React child that is not a single element.\n// - content a wrapper forwards with `<slot />` counts as its own roots, as\n// React's `children` passed on to Field are the elements themselves.\n// - As in React only `class` reaches the root element; other attributes are\n// dropped.\n\nexport type FieldChildProps = {\n id: string\n /** The label's id. Bind it to a control that the label's `for` cannot name, such as a Select trigger. */\n \"aria-labelledby\"?: string\n \"aria-describedby\"?: string\n \"aria-invalid\"?: boolean\n opticallyAlign?: \"start\" | \"end\"\n}\n\ntype Props = Record<string, unknown>\n\nconst CONTROL_SIZES: ReadonlySet<unknown> = new Set([\"3xs\", \"2xs\", \"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"2xl\", \"3xl\"])\n\n/** The slot props, recording whether the slot read them (the render-prop form). */\nconst trackUse = (target: FieldChildProps) => {\n const state = { used: false }\n const proxy = new Proxy(target, {\n get(object, key, receiver) {\n state.used = true\n return Reflect.get(object, key, receiver)\n },\n has(object, key) {\n state.used = true\n return Reflect.has(object, key)\n },\n ownKeys(object) {\n state.used = true\n return Reflect.ownKeys(object)\n },\n getOwnPropertyDescriptor(object, key) {\n state.used = true\n return Reflect.getOwnPropertyDescriptor(object, key)\n },\n })\n return { proxy, state }\n}\n\n/** Like React's `isValidElement` for a slot root: an element or a component. */\nconst isElementVNode = (node: VNode) => {\n const { type } = node\n if (type === Fragment || type === Text || type === Comment || type === Static) return false\n if (typeof type === \"object\" && type !== null && (\"__isTeleport\" in type || \"__isSuspense\" in type)) return false\n return true\n}\n\n/**\n * Template comments (`<!-- note -->`) are no children, like JSX comments.\n * The empty placeholder of a `v-if` that renders nothing (or of a `false`\n * child) still counts, like `{false}` in a React children array.\n */\nconst isTemplateComment = (node: VNodeArrayChildren[number]) =>\n isVNode(node) && node.type === Comment && !!node.children && node.children !== \"v-if\"\n\n/**\n * Unwraps content forwarded through a wrapper's `<slot />`: the fragment\n * `renderSlot` creates, keyed `_<slot name>`.\n */\nconst unwrapForwardedSlots = (nodes: VNodeArrayChildren): VNodeArrayChildren =>\n nodes.flatMap((node) =>\n isVNode(node) &&\n node.type === Fragment &&\n typeof node.key === \"string\" &&\n node.key.startsWith(\"_\") &&\n Array.isArray(node.children)\n ? unwrapForwardedSlots(node.children)\n : [node],\n )\n\n/** The one element a non-render-prop slot holds, if it holds exactly one. */\nconst singleElement = (nodes: VNodeArrayChildren): VNode | undefined => {\n const roots = unwrapForwardedSlots(nodes).filter((node) => !isTemplateComment(node))\n if (roots.length !== 1) return undefined\n const [root] = roots\n return isVNode(root) && isElementVNode(root) ? root : undefined\n}\n\n/** A child prop under its attribute name or its camelCase prop name. */\nconst childProp = (props: Props, name: string) => props[name] ?? props[camelize(name)]\n\n/**\n * `cloneElement(child, fieldProps)` with React Field's merging rules. A child\n * without its own name (`aria-label`, `aria-labelledby`, `label`, a `#label`\n * slot) is also labelled by the field's label, which names triggers `for`\n * cannot reach.\n */\nconst cloneWithFieldProps = (child: VNode, fieldChildProps: FieldChildProps, labelId: string): VNode => {\n const own: Props = { ...(child.props ?? {}) }\n const childDescribedBy = childProp(own, \"aria-describedby\") as string | undefined\n const childInvalid = childProp(own, \"aria-invalid\")\n const childSlots = child.children\n const childNamed =\n childProp(own, \"aria-label\") != null ||\n childProp(own, \"aria-labelledby\") != null ||\n own.label != null ||\n (childSlots != null && typeof childSlots === \"object\" && !Array.isArray(childSlots) && \"label\" in childSlots)\n\n const overrides: Props = {\n ...fieldChildProps,\n // Merge with the child's own associations instead of overwriting them\n \"aria-describedby\": [childDescribedBy, fieldChildProps[\"aria-describedby\"]].filter(Boolean).join(\" \") || undefined,\n \"aria-invalid\": childInvalid ?? fieldChildProps[\"aria-invalid\"],\n ...(!childNamed && { \"aria-labelledby\": labelId }),\n }\n\n // One spelling per prop, so the field's value is the one that applies\n for (const key of Object.keys(overrides)) {\n for (const spelling of [key, camelize(key), key.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)]) {\n delete own[spelling]\n }\n }\n\n return cloneVNode({ ...child, props: own } as VNode, overrides)\n}\n\nconst FieldComponent = defineComponent({\n name: \"Field\",\n inheritAttrs: false,\n props: {\n /** Label text for the field (or the `label` slot) */\n label: String,\n /** Helper text below the label, linked via `aria-describedby` (or the `description` slot) */\n description: String,\n /**\n * Error message below the control (or the `errorMessage` slot). When set,\n * the control gets `aria-invalid=\"true\"`. Rendered with FieldError.\n */\n errorMessage: String,\n /** Content at the end of the label row, such as a link that acts on the field (or the `labelAction` slot) */\n labelAction: String,\n /** Font size of the label, to match the control's size. @default the child control's `size`, else \"md\" */\n size: String as PropType<ControlSize>,\n /** Shows a required asterisk after the label. Visual only: no `required` attribute. @default false */\n required: { type: Boolean, default: false },\n /** Layout direction of label and control. @default \"vertical\" */\n orientation: { type: String as PropType<\"vertical\" | \"horizontal\">, default: \"vertical\" },\n /** Overrides the generated id set on the control and the label's `for`. A child's own `id` wins over both. */\n id: String,\n /** Optically aligns the control's text with surrounding content; passed to the control. */\n opticallyAlign: String as PropType<\"start\" | \"end\">,\n },\n slots: Object as SlotsType<{\n /** The control. Read the props to render them yourself (React's render prop). */\n default?: (fieldProps: FieldChildProps) => VNodeChild\n label?: () => VNodeChild\n labelAction?: () => VNodeChild\n description?: () => VNodeChild\n errorMessage?: () => VNodeChild\n }>,\n setup(props, { attrs, slots }) {\n const generatedId = useId()\n\n return () => {\n const { required, orientation, opticallyAlign } = props\n const fieldId = props.id || `field-${generatedId}`\n const labelId = `${fieldId}-label`\n\n const description = slots.description ? slots.description() : props.description\n const hasDescription = slots.description ? hasContent(description as VNodeArrayChildren) : !!description\n const errorMessage = slots.errorMessage ? slots.errorMessage() : props.errorMessage\n const hasError = slots.errorMessage ? hasContent(errorMessage as VNodeArrayChildren) : !!errorMessage\n\n const descriptionId = hasDescription ? `${fieldId}-description` : undefined\n const errorId = hasError ? `${fieldId}-error` : undefined\n\n // Build aria-describedby from description + error IDs\n const ariaDescribedBy = [descriptionId, errorId].filter(Boolean).join(\" \") || undefined\n const invalid = hasError\n\n // Props to inject into the child control\n const fieldChildProps: FieldChildProps = {\n \"id\": fieldId,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": invalid || undefined,\n ...(opticallyAlign && { opticallyAlign }),\n }\n\n // Resolve the children\n let resolvedChildren: VNodeArrayChildren | undefined\n let childSize: unknown\n // The control's id, which the label's `for` has to match\n let controlId = fieldId\n if (slots.default) {\n const { proxy, state } = trackUse({ ...fieldChildProps, \"aria-labelledby\": labelId })\n const nodes = slots.default(proxy) as VNodeArrayChildren\n const child = state.used ? undefined : singleElement(nodes)\n childSize = child?.props?.size\n controlId = (child?.props?.id as string | undefined) || fieldId\n resolvedChildren = child ? [cloneWithFieldProps(child, { ...fieldChildProps, id: controlId }, labelId)] : nodes\n }\n const size = props.size ?? (CONTROL_SIZES.has(childSize) ? (childSize as ControlSize) : \"md\")\n\n const labelAction = slots.labelAction ? slots.labelAction() : props.labelAction\n const hasLabelAction = slots.labelAction ? hasContent(labelAction as VNodeArrayChildren) : !!labelAction\n const labelElement = h(\"label\", { class: s.Label, id: labelId, for: controlId }, [\n slots.label ? slots.label() : props.label,\n required ? h(\"span\", { \"class\": s.RequiredIndicator, \"aria-hidden\": \"true\" }, \"*\") : null,\n ])\n\n return h(\n \"div\",\n {\n \"class\": clsx(s.Field, attrs.class as ClassValue),\n \"data-size\": size,\n \"data-orientation\": orientation,\n \"data-optically-align\": opticallyAlign,\n },\n [\n h(\"div\", { class: s.LabelGroup }, [\n hasLabelAction\n ? h(\"div\", { class: s.LabelRow }, [labelElement, h(\"div\", { class: s.LabelAction }, [labelAction as VNodeChild])])\n : labelElement,\n hasDescription ? h(\"div\", { class: s.Description, id: descriptionId }, [description as VNodeChild]) : null,\n ]),\n h(\"div\", { class: s.Content }, [\n h(\"div\", { class: s.Control }, resolvedChildren),\n hasError ? h(FieldError, { id: errorId }, () => [errorMessage as VNodeChild]) : null,\n ]),\n ],\n )\n }\n },\n})\n\ntype FieldOwnProps = InstanceType<typeof FieldComponent>[\"$props\"]\n\n/** Field props; `class` reaches the root element. */\nexport type FieldProps = FieldOwnProps & { class?: ClassValue }\n\n/** Form field wrapper with label, description, error and accessibility linking. */\nexport const Field = FieldComponent as typeof FieldComponent & { new (): { $props: FieldProps } }\n"]}
|
|
1
|
+
{"version":3,"file":"Field.js","sourceRoot":"","sources":["../../../../src/components/Field/Field.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,eAAe,EACf,CAAC,EACD,OAAO,EACP,KAAK,GAMN,MAAM,KAAK,CAAA;AAEZ,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,CAAC,MAAM,kDAAkD,CAAA;AAsChE,MAAM,aAAa,GAAyB,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;AAE/G,mFAAmF;AACnF,MAAM,QAAQ,GAAG,CAAC,MAAuB,EAAE,EAAE;IAC3C,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;IAC7B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,EAAE;QAC9B,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ;YACvB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;YACjB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;QAC3C,CAAC;QACD,GAAG,CAAC,MAAM,EAAE,GAAG;YACb,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;YACjB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACjC,CAAC;QACD,OAAO,CAAC,MAAM;YACZ,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;YACjB,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAChC,CAAC;QACD,wBAAwB,CAAC,MAAM,EAAE,GAAG;YAClC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;YACjB,OAAO,OAAO,CAAC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACtD,CAAC;KACF,CAAC,CAAA;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AACzB,CAAC,CAAA;AAED,gFAAgF;AAChF,MAAM,cAAc,GAAG,CAAC,IAAW,EAAE,EAAE;IACrC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;IACrB,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAA;IAC3F,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,IAAI,cAAc,IAAI,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IACjH,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,CAAC,IAAgC,EAAE,EAAE,CAC7D,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAA;AAEvF;;;GAGG;AACH,MAAM,oBAAoB,GAAG,CAAC,KAAyB,EAAsB,EAAE,CAC7E,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACrB,OAAO,CAAC,IAAI,CAAC;IACb,IAAI,CAAC,IAAI,KAAK,QAAQ;IACtB,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ;IAC5B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;IACxB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC1B,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC;IACrC,CAAC,CAAC,CAAC,IAAI,CAAC,CACX,CAAA;AAEH,6EAA6E;AAC7E,MAAM,aAAa,GAAG,CAAC,KAAyB,EAAqB,EAAE;IACrE,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAA;IACpF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACxC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;IACpB,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AACjE,CAAC,CAAA;AAED,wEAAwE;AACxE,MAAM,SAAS,GAAG,CAAC,KAAY,EAAE,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;AAEtF;;;;;GAKG;AACH,MAAM,mBAAmB,GAAG,CAAC,KAAY,EAAE,eAAgC,EAAE,OAAe,EAAS,EAAE;IACrG,MAAM,GAAG,GAAU,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAA;IAC7C,MAAM,gBAAgB,GAAG,SAAS,CAAC,GAAG,EAAE,kBAAkB,CAAuB,CAAA;IACjF,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IACnD,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAA;IACjC,MAAM,UAAU,GACd,SAAS,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,IAAI;QACpC,SAAS,CAAC,GAAG,EAAE,iBAAiB,CAAC,IAAI,IAAI;QACzC,GAAG,CAAC,KAAK,IAAI,IAAI;QACjB,CAAC,UAAU,IAAI,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,IAAI,UAAU,CAAC,CAAA;IAE/G,MAAM,SAAS,GAAU;QACvB,GAAG,eAAe;QAClB,sEAAsE;QACtE,kBAAkB,EAAE,CAAC,gBAAgB,EAAE,eAAe,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS;QAClH,cAAc,EAAE,YAAY,IAAI,eAAe,CAAC,cAAc,CAAC;QAC/D,GAAG,CAAC,CAAC,UAAU,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;KACnD,CAAA;IAED,sEAAsE;IACtE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;YACjG,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,EAAW,EAAE,SAAS,CAAC,CAAA;AACjE,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,eAAe,CAAC;IACrC,IAAI,EAAE,OAAO;IACb,YAAY,EAAE,KAAK;IACnB,KAAK,EAAE;QACL,qDAAqD;QACrD,KAAK,EAAE,MAAM;QACb,6FAA6F;QAC7F,WAAW,EAAE,MAAM;QACnB;;;WAGG;QACH,YAAY,EAAE,MAAM;QACpB,6GAA6G;QAC7G,WAAW,EAAE,MAAM;QACnB,0GAA0G;QAC1G,IAAI,EAAE,MAA+B;QACrC,sGAAsG;QACtG,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;QAC3C,+FAA+F;QAC/F,WAAW,EAAE,MAA6C;QAC1D,uFAAuF;QACvF,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;QACtC,8GAA8G;QAC9G,EAAE,EAAE,MAAM;QACV,2FAA2F;QAC3F,cAAc,EAAE,MAAmC;KACpD;IACD,KAAK,EAAE,MAOL;IACF,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QAC3B,MAAM,WAAW,GAAG,KAAK,EAAE,CAAA;QAE3B,OAAO,GAAG,EAAE;YACV,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,KAAK,CAAA;YAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;YAC1E,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,IAAI,SAAS,WAAW,EAAE,CAAA;YAClD,MAAM,OAAO,GAAG,GAAG,OAAO,QAAQ,CAAA;YAElC,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAA;YAC/E,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,WAAiC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAA;YACxG,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAA;YACnF,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,YAAkC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAA;YAErG,MAAM,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,cAAc,CAAC,CAAC,CAAC,SAAS,CAAA;YAC3E,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;YAEzD,sDAAsD;YACtD,MAAM,eAAe,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAA;YACvF,MAAM,OAAO,GAAG,QAAQ,CAAA;YAExB,yCAAyC;YACzC,MAAM,eAAe,GAAoB;gBACvC,IAAI,EAAE,OAAO;gBACb,kBAAkB,EAAE,eAAe;gBACnC,cAAc,EAAE,OAAO,IAAI,SAAS;gBACpC,GAAG,CAAC,cAAc,IAAI,EAAE,cAAc,EAAE,CAAC;aAC1C,CAAA;YAED,uBAAuB;YACvB,IAAI,gBAAgD,CAAA;YACpD,IAAI,SAAkB,CAAA;YACtB,yDAAyD;YACzD,IAAI,SAAS,GAAG,OAAO,CAAA;YACvB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,EAAE,GAAG,eAAe,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,CAAA;gBACrF,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAuB,CAAA;gBACxD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;gBAC3D,SAAS,GAAG,KAAK,EAAE,KAAK,EAAE,IAAI,CAAA;gBAC9B,SAAS,GAAI,KAAK,EAAE,KAAK,EAAE,EAAyB,IAAI,OAAO,CAAA;gBAC/D,gBAAgB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,EAAE,GAAG,eAAe,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;YACjH,CAAC;YACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,SAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAE7F,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAA;YAC/E,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,WAAiC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAA;YACxG,MAAM,YAAY,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE;gBAC/E,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;gBACzC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,iBAAiB,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;aAC1F,CAAC,CAAA;YAEF,OAAO,CAAC,CACN,KAAK,EACL;gBACE,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC;gBACjB,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,KAAmB,CAAC;gBACjD,WAAW,EAAE,IAAI;gBACjB,kBAAkB,EAAE,WAAW;gBAC/B,sBAAsB,EAAE,cAAc;gBACtC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;aACjC,EACD;gBACE,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE,EAAE;oBAChC,cAAc;wBACZ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAyB,CAAC,CAAC,CAAC,CAAC;wBAClH,CAAC,CAAC,YAAY;oBAChB,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,CAAC,WAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;iBAC3G,CAAC;gBACF,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE;oBAC7B,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC;oBAChD,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,YAA0B,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;iBACrF,CAAC;aACH,CACF,CAAA;QACH,CAAC,CAAA;IACH,CAAC;CACF,CAAC,CAAA;AAOF,mFAAmF;AACnF,MAAM,CAAC,MAAM,KAAK,GAAG,cAA4E,CAAA","sourcesContent":["import clsx, { type ClassValue } from \"clsx\"\nimport {\n Comment,\n Fragment,\n Static,\n Text,\n camelize,\n cloneVNode,\n defineComponent,\n h,\n isVNode,\n useId,\n type PropType,\n type SlotsType,\n type VNode,\n type VNodeArrayChildren,\n type VNodeChild,\n} from \"vue\"\nimport type { ControlSize } from \"@plexui/styles/types\"\nimport { FieldError } from \"../FieldError/index.js\"\nimport { hasContent } from \"../../lib/slotContent.js\"\nimport s from \"@plexui/styles/components/Field/Field.module.css\"\n\n// Vue port of packages/ui/src/components/Field/Field.tsx.\n//\n// - `label`, `description` and `errorMessage` take a string prop or a slot of\n// the same name (the slot wins), like React's ReactNode props.\n// - Children: React accepts an element, which Field clones with the field\n// props, or a render prop `(fieldProps) => ReactNode`, which it leaves alone.\n// Both are the default slot here, which receives the field props:\n// - a slot that reads them (`v-slot=\"fieldProps\"` + `v-bind=\"fieldProps\"`,\n// `v-slot=\"{ id }\"`, `(fieldProps) => h(...)`) is the render prop: its\n// content renders as it is.\n// - a slot that does not read them and holds exactly one element or\n// component gets it cloned like React's `cloneElement`: `opticallyAlign`\n// replaces the child's own, the child's own `id` stays and the label's\n// `for` follows it, `aria-describedby` is joined after the child's own\n// ids, and an explicit `aria-invalid` on the child wins. Template\n// comments do not count as children (JSX comments); the\n// placeholder of a `v-if` that renders nothing does, like `{false}` in a\n// React children array, so `<A v-if=\"x\" /><Input />` is not cloned.\n// - anything else (text, several roots, a `v-for` list) renders as it is,\n// like a React child that is not a single element.\n// - content a wrapper forwards with `<slot />` counts as its own roots, as\n// React's `children` passed on to Field are the elements themselves.\n// - As in React only `class` reaches the root element; other attributes are\n// dropped. On a `row` they all reach it, as React's rest props do.\n\nexport type FieldChildProps = {\n id: string\n /** The label's id. Bind it to a control that the label's `for` cannot name, such as a Select trigger. */\n \"aria-labelledby\"?: string\n \"aria-describedby\"?: string\n \"aria-invalid\"?: boolean\n opticallyAlign?: \"start\" | \"end\"\n}\n\ntype Props = Record<string, unknown>\n\nconst CONTROL_SIZES: ReadonlySet<unknown> = new Set([\"3xs\", \"2xs\", \"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"2xl\", \"3xl\"])\n\n/** The slot props, recording whether the slot read them (the render-prop form). */\nconst trackUse = (target: FieldChildProps) => {\n const state = { used: false }\n const proxy = new Proxy(target, {\n get(object, key, receiver) {\n state.used = true\n return Reflect.get(object, key, receiver)\n },\n has(object, key) {\n state.used = true\n return Reflect.has(object, key)\n },\n ownKeys(object) {\n state.used = true\n return Reflect.ownKeys(object)\n },\n getOwnPropertyDescriptor(object, key) {\n state.used = true\n return Reflect.getOwnPropertyDescriptor(object, key)\n },\n })\n return { proxy, state }\n}\n\n/** Like React's `isValidElement` for a slot root: an element or a component. */\nconst isElementVNode = (node: VNode) => {\n const { type } = node\n if (type === Fragment || type === Text || type === Comment || type === Static) return false\n if (typeof type === \"object\" && type !== null && (\"__isTeleport\" in type || \"__isSuspense\" in type)) return false\n return true\n}\n\n/**\n * Template comments (`<!-- note -->`) are no children, like JSX comments.\n * The empty placeholder of a `v-if` that renders nothing (or of a `false`\n * child) still counts, like `{false}` in a React children array.\n */\nconst isTemplateComment = (node: VNodeArrayChildren[number]) =>\n isVNode(node) && node.type === Comment && !!node.children && node.children !== \"v-if\"\n\n/**\n * Unwraps content forwarded through a wrapper's `<slot />`: the fragment\n * `renderSlot` creates, keyed `_<slot name>`.\n */\nconst unwrapForwardedSlots = (nodes: VNodeArrayChildren): VNodeArrayChildren =>\n nodes.flatMap((node) =>\n isVNode(node) &&\n node.type === Fragment &&\n typeof node.key === \"string\" &&\n node.key.startsWith(\"_\") &&\n Array.isArray(node.children)\n ? unwrapForwardedSlots(node.children)\n : [node],\n )\n\n/** The one element a non-render-prop slot holds, if it holds exactly one. */\nconst singleElement = (nodes: VNodeArrayChildren): VNode | undefined => {\n const roots = unwrapForwardedSlots(nodes).filter((node) => !isTemplateComment(node))\n if (roots.length !== 1) return undefined\n const [root] = roots\n return isVNode(root) && isElementVNode(root) ? root : undefined\n}\n\n/** A child prop under its attribute name or its camelCase prop name. */\nconst childProp = (props: Props, name: string) => props[name] ?? props[camelize(name)]\n\n/**\n * `cloneElement(child, fieldProps)` with React Field's merging rules. A child\n * without its own name (`aria-label`, `aria-labelledby`, `label`, a `#label`\n * slot) is also labelled by the field's label, which names triggers `for`\n * cannot reach.\n */\nconst cloneWithFieldProps = (child: VNode, fieldChildProps: FieldChildProps, labelId: string): VNode => {\n const own: Props = { ...(child.props ?? {}) }\n const childDescribedBy = childProp(own, \"aria-describedby\") as string | undefined\n const childInvalid = childProp(own, \"aria-invalid\")\n const childSlots = child.children\n const childNamed =\n childProp(own, \"aria-label\") != null ||\n childProp(own, \"aria-labelledby\") != null ||\n own.label != null ||\n (childSlots != null && typeof childSlots === \"object\" && !Array.isArray(childSlots) && \"label\" in childSlots)\n\n const overrides: Props = {\n ...fieldChildProps,\n // Merge with the child's own associations instead of overwriting them\n \"aria-describedby\": [childDescribedBy, fieldChildProps[\"aria-describedby\"]].filter(Boolean).join(\" \") || undefined,\n \"aria-invalid\": childInvalid ?? fieldChildProps[\"aria-invalid\"],\n ...(!childNamed && { \"aria-labelledby\": labelId }),\n }\n\n // One spelling per prop, so the field's value is the one that applies\n for (const key of Object.keys(overrides)) {\n for (const spelling of [key, camelize(key), key.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)]) {\n delete own[spelling]\n }\n }\n\n return cloneVNode({ ...child, props: own } as VNode, overrides)\n}\n\nconst FieldComponent = defineComponent({\n name: \"Field\",\n inheritAttrs: false,\n props: {\n /** Label text for the field (or the `label` slot) */\n label: String,\n /** Helper text below the label, linked via `aria-describedby` (or the `description` slot) */\n description: String,\n /**\n * Error message below the control (or the `errorMessage` slot). When set,\n * the control gets `aria-invalid=\"true\"`. Rendered with FieldError.\n */\n errorMessage: String,\n /** Content at the end of the label row, such as a link that acts on the field (or the `labelAction` slot) */\n labelAction: String,\n /** Font size of the label, to match the control's size. @default the child control's `size`, else \"md\" */\n size: String as PropType<ControlSize>,\n /** Shows a required asterisk after the label. Visual only: no `required` attribute. @default false */\n required: { type: Boolean, default: false },\n /** Layout direction of label and control. @default \"horizontal\" on a `row`, else \"vertical\" */\n orientation: String as PropType<\"vertical\" | \"horizontal\">,\n /** One line of a FieldGroup: label at the start, control at the end. @default false */\n row: { type: Boolean, default: false },\n /** Overrides the generated id set on the control and the label's `for`. A child's own `id` wins over both. */\n id: String,\n /** Optically aligns the control's text with surrounding content; passed to the control. */\n opticallyAlign: String as PropType<\"start\" | \"end\">,\n },\n slots: Object as SlotsType<{\n /** The control. Read the props to render them yourself (React's render prop). */\n default?: (fieldProps: FieldChildProps) => VNodeChild\n label?: () => VNodeChild\n labelAction?: () => VNodeChild\n description?: () => VNodeChild\n errorMessage?: () => VNodeChild\n }>,\n setup(props, { attrs, slots }) {\n const generatedId = useId()\n\n return () => {\n const { required, row, opticallyAlign } = props\n const orientation = props.orientation ?? (row ? \"horizontal\" : \"vertical\")\n const fieldId = props.id || `field-${generatedId}`\n const labelId = `${fieldId}-label`\n\n const description = slots.description ? slots.description() : props.description\n const hasDescription = slots.description ? hasContent(description as VNodeArrayChildren) : !!description\n const errorMessage = slots.errorMessage ? slots.errorMessage() : props.errorMessage\n const hasError = slots.errorMessage ? hasContent(errorMessage as VNodeArrayChildren) : !!errorMessage\n\n const descriptionId = hasDescription ? `${fieldId}-description` : undefined\n const errorId = hasError ? `${fieldId}-error` : undefined\n\n // Build aria-describedby from description + error IDs\n const ariaDescribedBy = [descriptionId, errorId].filter(Boolean).join(\" \") || undefined\n const invalid = hasError\n\n // Props to inject into the child control\n const fieldChildProps: FieldChildProps = {\n \"id\": fieldId,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-invalid\": invalid || undefined,\n ...(opticallyAlign && { opticallyAlign }),\n }\n\n // Resolve the children\n let resolvedChildren: VNodeArrayChildren | undefined\n let childSize: unknown\n // The control's id, which the label's `for` has to match\n let controlId = fieldId\n if (slots.default) {\n const { proxy, state } = trackUse({ ...fieldChildProps, \"aria-labelledby\": labelId })\n const nodes = slots.default(proxy) as VNodeArrayChildren\n const child = state.used ? undefined : singleElement(nodes)\n childSize = child?.props?.size\n controlId = (child?.props?.id as string | undefined) || fieldId\n resolvedChildren = child ? [cloneWithFieldProps(child, { ...fieldChildProps, id: controlId }, labelId)] : nodes\n }\n const size = props.size ?? (CONTROL_SIZES.has(childSize) ? (childSize as ControlSize) : \"md\")\n\n const labelAction = slots.labelAction ? slots.labelAction() : props.labelAction\n const hasLabelAction = slots.labelAction ? hasContent(labelAction as VNodeArrayChildren) : !!labelAction\n const labelElement = h(\"label\", { class: s.Label, id: labelId, for: controlId }, [\n slots.label ? slots.label() : props.label,\n required ? h(\"span\", { \"class\": s.RequiredIndicator, \"aria-hidden\": \"true\" }, \"*\") : null,\n ])\n\n return h(\n \"div\",\n {\n ...(row && attrs),\n \"class\": clsx(s.Field, attrs.class as ClassValue),\n \"data-size\": size,\n \"data-orientation\": orientation,\n \"data-optically-align\": opticallyAlign,\n \"data-row\": row ? \"\" : undefined,\n },\n [\n h(\"div\", { class: s.LabelGroup }, [\n hasLabelAction\n ? h(\"div\", { class: s.LabelRow }, [labelElement, h(\"div\", { class: s.LabelAction }, [labelAction as VNodeChild])])\n : labelElement,\n hasDescription ? h(\"div\", { class: s.Description, id: descriptionId }, [description as VNodeChild]) : null,\n ]),\n h(\"div\", { class: s.Content }, [\n h(\"div\", { class: s.Control }, resolvedChildren),\n hasError ? h(FieldError, { id: errorId }, () => [errorMessage as VNodeChild]) : null,\n ]),\n ],\n )\n }\n },\n})\n\ntype FieldOwnProps = InstanceType<typeof FieldComponent>[\"$props\"]\n\n/** Field props; `class` reaches the root element. */\nexport type FieldProps = FieldOwnProps & { class?: ClassValue }\n\n/** Form field wrapper with label, description, error and accessibility linking. */\nexport const Field = FieldComponent as typeof FieldComponent & { new (): { $props: FieldProps } }\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import clsx, {} from "clsx";
|
|
2
|
+
import { defineComponent, h, useId } from "vue";
|
|
3
|
+
import { hasContent } from "../../lib/slotContent.js";
|
|
4
|
+
import s from "@plexui/styles/components/FieldGroup/FieldGroup.module.css";
|
|
5
|
+
// Vue port of packages/ui/src/components/FieldGroup/FieldGroup.tsx.
|
|
6
|
+
//
|
|
7
|
+
// - `title` and `description` take a string prop or a slot of the same name,
|
|
8
|
+
// like React's ReactNode props. `action` and `footer` are slots here.
|
|
9
|
+
// - Attributes reach the root `section`, as React's rest props do.
|
|
10
|
+
const FieldGroupComponent = defineComponent({
|
|
11
|
+
name: "FieldGroup",
|
|
12
|
+
inheritAttrs: false,
|
|
13
|
+
props: {
|
|
14
|
+
/** Heading over the block (or the `title` slot); it names the group */
|
|
15
|
+
title: String,
|
|
16
|
+
/** Line under the title (or the `description` slot) */
|
|
17
|
+
description: String,
|
|
18
|
+
/** Class for the block that holds the rows */
|
|
19
|
+
bodyClass: [String, Array, Object],
|
|
20
|
+
},
|
|
21
|
+
slots: Object,
|
|
22
|
+
setup(props, { attrs, slots }) {
|
|
23
|
+
const titleId = `field-group-${useId()}`;
|
|
24
|
+
return () => {
|
|
25
|
+
const title = slots.title ? slots.title() : props.title;
|
|
26
|
+
const hasTitle = slots.title ? hasContent(title) : !!title;
|
|
27
|
+
const description = slots.description ? slots.description() : props.description;
|
|
28
|
+
const hasDescription = slots.description ? hasContent(description) : !!description;
|
|
29
|
+
const action = slots.action?.();
|
|
30
|
+
const hasAction = !!action && hasContent(action);
|
|
31
|
+
return h("section", {
|
|
32
|
+
"role": "group",
|
|
33
|
+
"aria-labelledby": hasTitle ? titleId : undefined,
|
|
34
|
+
...attrs,
|
|
35
|
+
"class": clsx(s.FieldGroup, attrs.class),
|
|
36
|
+
}, [
|
|
37
|
+
hasTitle || hasDescription || hasAction
|
|
38
|
+
? h("div", { class: s.Header }, [
|
|
39
|
+
h("div", { class: s.HeaderText }, [
|
|
40
|
+
hasTitle ? h("h2", { class: s.Title, id: titleId }, [title]) : null,
|
|
41
|
+
hasDescription ? h("p", { class: s.Description }, [description]) : null,
|
|
42
|
+
]),
|
|
43
|
+
hasAction ? action : null,
|
|
44
|
+
])
|
|
45
|
+
: null,
|
|
46
|
+
h("div", { class: clsx(s.Body, props.bodyClass) }, [slots.default?.()]),
|
|
47
|
+
slots.footer?.(),
|
|
48
|
+
]);
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
/** A titled block of rows: `Field row` lines with hairlines between them. */
|
|
53
|
+
export const FieldGroup = FieldGroupComponent;
|
|
54
|
+
//# sourceMappingURL=FieldGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldGroup.js","sourceRoot":"","sources":["../../../../src/components/FieldGroup/FieldGroup.ts"],"names":[],"mappings":"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","sourcesContent":["import clsx, { type ClassValue } from \"clsx\"\nimport { defineComponent, h, useId, type PropType, type SlotsType, type VNodeArrayChildren, type VNodeChild } from \"vue\"\nimport { hasContent } from \"../../lib/slotContent.js\"\nimport s from \"@plexui/styles/components/FieldGroup/FieldGroup.module.css\"\n\n// Vue port of packages/ui/src/components/FieldGroup/FieldGroup.tsx.\n//\n// - `title` and `description` take a string prop or a slot of the same name,\n// like React's ReactNode props. `action` and `footer` are slots here.\n// - Attributes reach the root `section`, as React's rest props do.\n\nconst FieldGroupComponent = defineComponent({\n name: \"FieldGroup\",\n inheritAttrs: false,\n props: {\n /** Heading over the block (or the `title` slot); it names the group */\n title: String,\n /** Line under the title (or the `description` slot) */\n description: String,\n /** Class for the block that holds the rows */\n bodyClass: [String, Array, Object] as PropType<ClassValue>,\n },\n slots: Object as SlotsType<{\n /** The rows: `Field row`, or rows of your own. */\n default?: () => VNodeChild\n title?: () => VNodeChild\n description?: () => VNodeChild\n /** Content at the end of the header, such as a button */\n action?: () => VNodeChild\n /** Content under the block, such as a note */\n footer?: () => VNodeChild\n }>,\n setup(props, { attrs, slots }) {\n const titleId = `field-group-${useId()}`\n\n return () => {\n const title = slots.title ? slots.title() : props.title\n const hasTitle = slots.title ? hasContent(title as VNodeArrayChildren) : !!title\n const description = slots.description ? slots.description() : props.description\n const hasDescription = slots.description ? hasContent(description as VNodeArrayChildren) : !!description\n const action = slots.action?.()\n const hasAction = !!action && hasContent(action as VNodeArrayChildren)\n\n return h(\n \"section\",\n {\n \"role\": \"group\",\n \"aria-labelledby\": hasTitle ? titleId : undefined,\n ...attrs,\n \"class\": clsx(s.FieldGroup, attrs.class as ClassValue),\n },\n [\n hasTitle || hasDescription || hasAction\n ? h(\"div\", { class: s.Header }, [\n h(\"div\", { class: s.HeaderText }, [\n hasTitle ? h(\"h2\", { class: s.Title, id: titleId }, [title as VNodeChild]) : null,\n hasDescription ? h(\"p\", { class: s.Description }, [description as VNodeChild]) : null,\n ]),\n hasAction ? action : null,\n ])\n : null,\n h(\"div\", { class: clsx(s.Body, props.bodyClass) }, [slots.default?.()]),\n slots.footer?.(),\n ],\n )\n }\n },\n})\n\ntype FieldGroupOwnProps = InstanceType<typeof FieldGroupComponent>[\"$props\"]\n\n/** FieldGroup props; attributes reach the root element. */\nexport type FieldGroupProps = FieldGroupOwnProps & { class?: ClassValue }\n\n/** A titled block of rows: `Field row` lines with hairlines between them. */\nexport const FieldGroup = FieldGroupComponent as typeof FieldGroupComponent & { new (): { $props: FieldGroupProps } }\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/FieldGroup/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAA","sourcesContent":["export { FieldGroup, type FieldGroupProps } from \"./FieldGroup.js\"\n"]}
|
|
@@ -54,6 +54,10 @@ const FloatingLabelInputComponent = defineComponent({
|
|
|
54
54
|
multiline: { type: Boolean, default: false },
|
|
55
55
|
/** Number of visible text lines when `multiline` is true */
|
|
56
56
|
rows: { type: Number, default: 2 },
|
|
57
|
+
/** Where the label rests once it floats: on the border, or inside the box with the value under it (always the rounded box). @default "border" */
|
|
58
|
+
labelPlacement: { type: String, default: "border" },
|
|
59
|
+
/** Pill shape. `false` takes the rounded box of the other fields. @default true */
|
|
60
|
+
pill: { type: Boolean, default: true },
|
|
57
61
|
id: String,
|
|
58
62
|
name: String,
|
|
59
63
|
type: { type: String, default: "text" },
|
|
@@ -213,7 +217,12 @@ const FloatingLabelInputComponent = defineComponent({
|
|
|
213
217
|
// `default-value`, as React keeps a textarea's defaultValue
|
|
214
218
|
const { value: _value, ...textareaControlProps } = controlProps;
|
|
215
219
|
const textContent = String(props.value ?? props.defaultValue ?? "");
|
|
216
|
-
|
|
220
|
+
const inside = props.labelPlacement === "inside";
|
|
221
|
+
return h("div", {
|
|
222
|
+
"class": clsx(s.Root, className),
|
|
223
|
+
"data-label-placement": inside ? "inside" : undefined,
|
|
224
|
+
"data-pill": props.pill && !inside ? "" : undefined,
|
|
225
|
+
}, [
|
|
217
226
|
h("div", {
|
|
218
227
|
"class": clsx(s.FieldFootprint, { [s.HasValue]: hasValue.value || !!startAdornment }),
|
|
219
228
|
"data-focused": focused.value ? "" : undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingLabelInput.js","sourceRoot":"","sources":["../../../../src/components/FloatingLabelInput/FloatingLabelInput.ts"],"names":[],"mappings":"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","sourcesContent":["import clsx from \"clsx\"\nimport { defineComponent, h, mergeProps, nextTick, onMounted, ref, useId, watch, withDirectives, type InputHTMLAttributes, type PropType, type VNodeChild } from \"vue\"\nimport { Eye, EyeOff, X } from \"../Icon/index.js\"\nimport { vDefaultValue, vServerText } from \"../../lib/defaultValue.js\"\nimport { hasContent } from \"../../lib/slotContent.js\"\nimport s from \"@plexui/styles/components/FloatingLabelInput/FloatingLabelInput.module.css\"\n\n// A fallthrough listener is a function or, when merged, an array of them\nconst callListeners = (listener: unknown, evt: Event) => {\n for (const fn of Array.isArray(listener) ? listener : [listener]) {\n if (typeof fn === \"function\") fn(evt)\n }\n}\n\n// Attributes that only mean something on <input>; everything else (required,\n// maxlength, placeholder, key and clipboard listeners, aria-*, data-*) also\n// applies to the multiline <textarea>, as in React\nconst INPUT_ONLY_ATTRS = new Set([\n \"accept\", \"alt\", \"capture\", \"checked\", \"height\", \"list\", \"max\", \"min\", \"multiple\",\n \"pattern\", \"size\", \"src\", \"step\", \"width\", \"formaction\", \"formenctype\",\n \"formmethod\", \"formnovalidate\", \"formtarget\",\n])\n\nconst textareaAttrs = (attrs: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(attrs).filter(([key]) => !INPUT_ONLY_ATTRS.has(key.toLowerCase())))\n\n/**\n * Port of packages/ui/src/components/FloatingLabelInput/FloatingLabelInput.tsx.\n * Attributes other than `class` go to the <input>, or to the `multiline`\n * <textarea> except the input-only ones, as in React. `value` +\n * `update:value` support `v-model:value`.\n */\nconst FloatingLabelInputComponent = defineComponent({\n name: \"FloatingLabelInput\",\n inheritAttrs: false,\n props: {\n /** Label text for the floating label */\n label: { type: String, required: true },\n /** Error message to display below the input */\n errorMessage: String,\n /** Mark the input as invalid. @default false (or true if errorMessage is provided) */\n invalid: { type: Boolean, default: undefined },\n /** Disables the input visually and from interactions */\n disabled: { type: Boolean, default: false },\n /** Makes the input read-only */\n readOnly: { type: Boolean, default: false },\n /** Native spelling of `readOnly` (`<FloatingLabelInput readonly />`) */\n readonly: { type: Boolean, default: false },\n /** Shows the clear button; called when it is clicked */\n onClear: Function as PropType<() => void>,\n /** Allow autofill extensions to appear in the input */\n allowAutofillExtensions: { type: Boolean, default: false },\n /** Helper text below the input (or the `description` slot) */\n description: String,\n /** Built-in reveal toggle. @default true when type=\"password\" and no end adornment */\n revealable: { type: Boolean, default: undefined },\n /** Render as a multi-line textarea instead of a single-line input */\n multiline: { type: Boolean, default: false },\n /** Number of visible text lines when `multiline` is true */\n rows: { type: Number, default: 2 },\n id: String,\n name: String,\n type: { type: String, default: \"text\" },\n value: { type: [String, Number] as PropType<string | number>, default: undefined },\n defaultValue: { type: [String, Number] as PropType<string | number>, default: undefined },\n },\n emits: {\n \"update:value\": (_value: string) => true,\n \"autofill\": () => true,\n \"revealedChange\": (_revealed: boolean) => true,\n },\n setup(props, { attrs, slots, emit, expose }) {\n const inputRef = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)\n const generatedId = useId()\n const focused = ref(false)\n const hasValue = ref(!!(props.value !== undefined ? props.value : props.defaultValue))\n const revealed = ref(false)\n\n // Sync hasValue with controlled value prop\n watch(\n () => props.value,\n (value) => {\n if (value !== undefined) hasValue.value = !!value\n },\n )\n\n const autoResize = () => {\n const el = inputRef.value\n if (!props.multiline || !el) return\n el.style.height = \"auto\"\n el.style.height = `${el.scrollHeight}px`\n }\n // The multiline <textarea> gets its value imperatively, like React DOM: a\n // `value` prop would make Vue mirror it into a `value` attribute, which\n // React never renders (its text content carries the value instead)\n const syncTextareaValue = () => {\n const el = inputRef.value\n if (!props.multiline || !el || props.value === undefined) return\n const value = String(props.value)\n if (el.value !== value) el.value = value\n }\n onMounted(() => {\n // React's initTextarea: the initial text becomes the (dirty) value\n const el = inputRef.value\n if (props.multiline && el && el.textContent) el.value = el.textContent\n autoResize()\n })\n // Also resize when a controlled value or rows changes without a keystroke\n watch(\n [() => props.multiline, () => props.value, () => props.rows],\n () => {\n syncTextareaValue()\n autoResize()\n },\n { flush: \"post\" },\n )\n\n // Handle clicks on the container to focus the input\n const handleContainerMouseDown = (evt: MouseEvent) => {\n const input = inputRef.value\n if (!evt.target || !(evt.target instanceof Element) || !input) {\n return\n }\n if (input.contains(evt.target)) {\n return\n }\n if (evt.target.closest(\"button, [type='button'], [role='button']\")) {\n return\n }\n evt.preventDefault()\n if (document.activeElement !== input) {\n input.focus()\n }\n // email, number and other types without the selection API throw on setSelectionRange\n if (input.selectionStart === null) return\n const length = input.value.length\n input.setSelectionRange(length, length)\n }\n\n // The clear button unmounts once the value is gone, so keep focus in the field\n const handleClear = (evt: MouseEvent) => {\n inputRef.value?.focus()\n ;(props.onClear as ((evt: MouseEvent) => void) | undefined)?.(evt)\n }\n\n const handleInput = (evt: Event) => {\n const target = evt.currentTarget as HTMLInputElement\n hasValue.value = !!target.value\n emit(\"update:value\", target.value)\n autoResize()\n // Like a React controlled input, a `value` the parent does not update\n // is put back (Vue only re-applies `value` when this component renders)\n void nextTick(() => {\n if (props.value === undefined) return\n const value = String(props.value)\n if (target.value !== value) target.value = value\n })\n }\n\n const handleAnimationStart = (evt: AnimationEvent) => {\n // Detect browser autofill\n if (evt.animationName === \"native-autofill-in\") {\n hasValue.value = true\n emit(\"autofill\")\n }\n }\n\n const handleRevealToggle = () => {\n revealed.value = !revealed.value\n emit(\"revealedChange\", revealed.value)\n }\n\n expose({ focus: () => inputRef.value?.focus(), input: inputRef })\n\n return () => {\n const inputId = props.id || `floating-label-input-${generatedId}`\n // Slots that render nothing (a false v-if) count as absent, like a falsy ReactNode\n const descriptionSlot = slots.description?.()\n const description: VNodeChild = hasContent(descriptionSlot) ? descriptionSlot : props.description\n const descriptionId = description ? `${inputId}-description` : undefined\n const errorId = props.errorMessage ? `${inputId}-error` : undefined\n const startAdornmentSlot = slots.startAdornment?.()\n const startAdornment = hasContent(startAdornmentSlot) ? startAdornmentSlot : undefined\n const endAdornmentSlot = slots.endAdornment?.()\n const endAdornment = hasContent(endAdornmentSlot) ? endAdornmentSlot : undefined\n const readOnly = props.readOnly || props.readonly\n // Caller focus/blur listeners run from the shared handlers\n const {\n \"class\": className,\n \"aria-describedby\": ariaDescribedByAttr,\n \"onFocus\": onFocusAttr,\n \"onBlur\": onBlurAttr,\n ...restAttrs\n } = attrs\n\n const invalid = props.invalid ?? !!props.errorMessage\n // Determine if clear button should be shown\n const showClearButton = !!props.onClear && hasValue.value && !props.disabled && !readOnly\n // Built-in password reveal toggle\n const isPassword = props.type === \"password\"\n const revealable = props.revealable ?? (isPassword && !endAdornment)\n const showRevealButton = revealable && !props.disabled\n const effectiveType = isPassword && revealed.value ? \"text\" : props.type\n // Merge aria-describedby with error id\n const ariaDescribedBy = [ariaDescribedByAttr, errorId, descriptionId].filter(Boolean).join(\" \") || undefined\n\n const controlProps = {\n \"ref\": inputRef,\n \"id\": inputId,\n \"name\": props.name,\n // Vue re-applies a present `value` key on every render, so an\n // uncontrolled field must not carry one (it would reset typed text)\n ...(props.value !== undefined ? { value: props.value } : {}),\n \"disabled\": props.disabled,\n \"readonly\": readOnly,\n // An explicit aria-invalid (e.g. from Field) wins over the computed state\n \"aria-invalid\": restAttrs[\"aria-invalid\"] ?? (invalid ? true : undefined),\n \"aria-describedby\": ariaDescribedBy,\n \"onInput\": handleInput,\n \"onFocus\": (evt: FocusEvent) => {\n focused.value = true\n callListeners(onFocusAttr, evt)\n },\n \"onBlur\": (evt: FocusEvent) => {\n focused.value = false\n callListeners(onBlurAttr, evt)\n },\n }\n // Uncontrolled: `vDefaultValue` sets the initial value (server markup,\n // hydration and later changes as in React)\n const initialValue = props.value === undefined ? props.defaultValue : undefined\n // The textarea's text content follows the controlled value, else\n // `default-value`, as React keeps a textarea's defaultValue\n const { value: _value, ...textareaControlProps } = controlProps as typeof controlProps & { value?: unknown }\n const textContent = String(props.value ?? props.defaultValue ?? \"\")\n\n return h(\"div\", { class: clsx(s.Root, className as string | undefined) }, [\n h(\n \"div\",\n {\n \"class\": clsx(s.FieldFootprint, { [s.HasValue!]: hasValue.value || !!startAdornment }),\n \"data-focused\": focused.value ? \"\" : undefined,\n \"data-has-value\": hasValue.value ? \"\" : undefined,\n \"data-invalid\": invalid ? \"\" : undefined,\n \"data-disabled\": props.disabled ? \"\" : undefined,\n \"data-readonly\": readOnly ? \"\" : undefined,\n \"data-multiline\": props.multiline ? \"\" : undefined,\n \"onMousedown\": handleContainerMouseDown,\n },\n [\n h(\"label\", { class: s.TypeableLabel, for: inputId }, [\n h(\"div\", { class: s.LabelPositioner }, [h(\"div\", { class: s.LabelText }, props.label)]),\n ]),\n startAdornment ? h(\"div\", { class: s.StartAdornment }, startAdornment) : null,\n props.multiline\n ? withDirectives(\n h(\n \"textarea\",\n mergeProps(textareaAttrs(restAttrs), {\n ...textareaControlProps,\n rows: props.rows,\n class: s.Textarea,\n textContent,\n }),\n ),\n [[vServerText, textContent]],\n )\n : withDirectives(\n h(\n \"input\",\n mergeProps(restAttrs, {\n ...controlProps,\n \"type\": effectiveType,\n \"class\": s.Input,\n \"onAnimationstart\": handleAnimationStart,\n \"data-lpignore\": props.allowAutofillExtensions ? undefined : true,\n \"data-1p-ignore\": props.allowAutofillExtensions ? undefined : true,\n }),\n ),\n [[vDefaultValue, initialValue]],\n ),\n endAdornment ? h(\"div\", { class: s.EndAdornment }, endAdornment) : null,\n showClearButton\n ? h(\"button\", { \"type\": \"button\", \"aria-label\": \"Clear input\", \"class\": s.ClearButton, \"onClick\": handleClear }, [h(X)])\n : null,\n showRevealButton\n ? h(\n \"button\",\n { \"type\": \"button\", \"aria-label\": revealed.value ? \"Hide\" : \"Show\", \"class\": s.RevealButton, \"onClick\": handleRevealToggle },\n [revealed.value ? h(EyeOff) : h(Eye)],\n )\n : null,\n ],\n ),\n props.errorMessage ? h(\"div\", { id: errorId, class: s.ErrorMessage, role: \"alert\" }, props.errorMessage) : null,\n description ? h(\"div\", { id: descriptionId, class: s.Description }, description) : null,\n ])\n }\n },\n})\n\ntype FloatingLabelInputOwnProps = InstanceType<typeof FloatingLabelInputComponent>[\"$props\"]\n\n/** FloatingLabelInput props plus the native <input> attributes that fall through to it, as in React. */\nexport type FloatingLabelInputProps = FloatingLabelInputOwnProps &\n Omit<InputHTMLAttributes, keyof FloatingLabelInputOwnProps>\n\n/** Text input whose label floats above the value, with optional reveal toggle and multiline mode. */\nexport const FloatingLabelInput = FloatingLabelInputComponent as typeof FloatingLabelInputComponent & {\n new (): { $props: FloatingLabelInputProps }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FloatingLabelInput.js","sourceRoot":"","sources":["../../../../src/components/FloatingLabelInput/FloatingLabelInput.ts"],"names":[],"mappings":"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","sourcesContent":["import clsx from \"clsx\"\nimport { defineComponent, h, mergeProps, nextTick, onMounted, ref, useId, watch, withDirectives, type InputHTMLAttributes, type PropType, type VNodeChild } from \"vue\"\nimport { Eye, EyeOff, X } from \"../Icon/index.js\"\nimport { vDefaultValue, vServerText } from \"../../lib/defaultValue.js\"\nimport { hasContent } from \"../../lib/slotContent.js\"\nimport s from \"@plexui/styles/components/FloatingLabelInput/FloatingLabelInput.module.css\"\n\n// A fallthrough listener is a function or, when merged, an array of them\nconst callListeners = (listener: unknown, evt: Event) => {\n for (const fn of Array.isArray(listener) ? listener : [listener]) {\n if (typeof fn === \"function\") fn(evt)\n }\n}\n\n// Attributes that only mean something on <input>; everything else (required,\n// maxlength, placeholder, key and clipboard listeners, aria-*, data-*) also\n// applies to the multiline <textarea>, as in React\nconst INPUT_ONLY_ATTRS = new Set([\n \"accept\", \"alt\", \"capture\", \"checked\", \"height\", \"list\", \"max\", \"min\", \"multiple\",\n \"pattern\", \"size\", \"src\", \"step\", \"width\", \"formaction\", \"formenctype\",\n \"formmethod\", \"formnovalidate\", \"formtarget\",\n])\n\nconst textareaAttrs = (attrs: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(attrs).filter(([key]) => !INPUT_ONLY_ATTRS.has(key.toLowerCase())))\n\n/**\n * Port of packages/ui/src/components/FloatingLabelInput/FloatingLabelInput.tsx.\n * Attributes other than `class` go to the <input>, or to the `multiline`\n * <textarea> except the input-only ones, as in React. `value` +\n * `update:value` support `v-model:value`.\n */\nconst FloatingLabelInputComponent = defineComponent({\n name: \"FloatingLabelInput\",\n inheritAttrs: false,\n props: {\n /** Label text for the floating label */\n label: { type: String, required: true },\n /** Error message to display below the input */\n errorMessage: String,\n /** Mark the input as invalid. @default false (or true if errorMessage is provided) */\n invalid: { type: Boolean, default: undefined },\n /** Disables the input visually and from interactions */\n disabled: { type: Boolean, default: false },\n /** Makes the input read-only */\n readOnly: { type: Boolean, default: false },\n /** Native spelling of `readOnly` (`<FloatingLabelInput readonly />`) */\n readonly: { type: Boolean, default: false },\n /** Shows the clear button; called when it is clicked */\n onClear: Function as PropType<() => void>,\n /** Allow autofill extensions to appear in the input */\n allowAutofillExtensions: { type: Boolean, default: false },\n /** Helper text below the input (or the `description` slot) */\n description: String,\n /** Built-in reveal toggle. @default true when type=\"password\" and no end adornment */\n revealable: { type: Boolean, default: undefined },\n /** Render as a multi-line textarea instead of a single-line input */\n multiline: { type: Boolean, default: false },\n /** Number of visible text lines when `multiline` is true */\n rows: { type: Number, default: 2 },\n /** Where the label rests once it floats: on the border, or inside the box with the value under it (always the rounded box). @default \"border\" */\n labelPlacement: { type: String as PropType<\"border\" | \"inside\">, default: \"border\" },\n /** Pill shape. `false` takes the rounded box of the other fields. @default true */\n pill: { type: Boolean, default: true },\n id: String,\n name: String,\n type: { type: String, default: \"text\" },\n value: { type: [String, Number] as PropType<string | number>, default: undefined },\n defaultValue: { type: [String, Number] as PropType<string | number>, default: undefined },\n },\n emits: {\n \"update:value\": (_value: string) => true,\n \"autofill\": () => true,\n \"revealedChange\": (_revealed: boolean) => true,\n },\n setup(props, { attrs, slots, emit, expose }) {\n const inputRef = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)\n const generatedId = useId()\n const focused = ref(false)\n const hasValue = ref(!!(props.value !== undefined ? props.value : props.defaultValue))\n const revealed = ref(false)\n\n // Sync hasValue with controlled value prop\n watch(\n () => props.value,\n (value) => {\n if (value !== undefined) hasValue.value = !!value\n },\n )\n\n const autoResize = () => {\n const el = inputRef.value\n if (!props.multiline || !el) return\n el.style.height = \"auto\"\n el.style.height = `${el.scrollHeight}px`\n }\n // The multiline <textarea> gets its value imperatively, like React DOM: a\n // `value` prop would make Vue mirror it into a `value` attribute, which\n // React never renders (its text content carries the value instead)\n const syncTextareaValue = () => {\n const el = inputRef.value\n if (!props.multiline || !el || props.value === undefined) return\n const value = String(props.value)\n if (el.value !== value) el.value = value\n }\n onMounted(() => {\n // React's initTextarea: the initial text becomes the (dirty) value\n const el = inputRef.value\n if (props.multiline && el && el.textContent) el.value = el.textContent\n autoResize()\n })\n // Also resize when a controlled value or rows changes without a keystroke\n watch(\n [() => props.multiline, () => props.value, () => props.rows],\n () => {\n syncTextareaValue()\n autoResize()\n },\n { flush: \"post\" },\n )\n\n // Handle clicks on the container to focus the input\n const handleContainerMouseDown = (evt: MouseEvent) => {\n const input = inputRef.value\n if (!evt.target || !(evt.target instanceof Element) || !input) {\n return\n }\n if (input.contains(evt.target)) {\n return\n }\n if (evt.target.closest(\"button, [type='button'], [role='button']\")) {\n return\n }\n evt.preventDefault()\n if (document.activeElement !== input) {\n input.focus()\n }\n // email, number and other types without the selection API throw on setSelectionRange\n if (input.selectionStart === null) return\n const length = input.value.length\n input.setSelectionRange(length, length)\n }\n\n // The clear button unmounts once the value is gone, so keep focus in the field\n const handleClear = (evt: MouseEvent) => {\n inputRef.value?.focus()\n ;(props.onClear as ((evt: MouseEvent) => void) | undefined)?.(evt)\n }\n\n const handleInput = (evt: Event) => {\n const target = evt.currentTarget as HTMLInputElement\n hasValue.value = !!target.value\n emit(\"update:value\", target.value)\n autoResize()\n // Like a React controlled input, a `value` the parent does not update\n // is put back (Vue only re-applies `value` when this component renders)\n void nextTick(() => {\n if (props.value === undefined) return\n const value = String(props.value)\n if (target.value !== value) target.value = value\n })\n }\n\n const handleAnimationStart = (evt: AnimationEvent) => {\n // Detect browser autofill\n if (evt.animationName === \"native-autofill-in\") {\n hasValue.value = true\n emit(\"autofill\")\n }\n }\n\n const handleRevealToggle = () => {\n revealed.value = !revealed.value\n emit(\"revealedChange\", revealed.value)\n }\n\n expose({ focus: () => inputRef.value?.focus(), input: inputRef })\n\n return () => {\n const inputId = props.id || `floating-label-input-${generatedId}`\n // Slots that render nothing (a false v-if) count as absent, like a falsy ReactNode\n const descriptionSlot = slots.description?.()\n const description: VNodeChild = hasContent(descriptionSlot) ? descriptionSlot : props.description\n const descriptionId = description ? `${inputId}-description` : undefined\n const errorId = props.errorMessage ? `${inputId}-error` : undefined\n const startAdornmentSlot = slots.startAdornment?.()\n const startAdornment = hasContent(startAdornmentSlot) ? startAdornmentSlot : undefined\n const endAdornmentSlot = slots.endAdornment?.()\n const endAdornment = hasContent(endAdornmentSlot) ? endAdornmentSlot : undefined\n const readOnly = props.readOnly || props.readonly\n // Caller focus/blur listeners run from the shared handlers\n const {\n \"class\": className,\n \"aria-describedby\": ariaDescribedByAttr,\n \"onFocus\": onFocusAttr,\n \"onBlur\": onBlurAttr,\n ...restAttrs\n } = attrs\n\n const invalid = props.invalid ?? !!props.errorMessage\n // Determine if clear button should be shown\n const showClearButton = !!props.onClear && hasValue.value && !props.disabled && !readOnly\n // Built-in password reveal toggle\n const isPassword = props.type === \"password\"\n const revealable = props.revealable ?? (isPassword && !endAdornment)\n const showRevealButton = revealable && !props.disabled\n const effectiveType = isPassword && revealed.value ? \"text\" : props.type\n // Merge aria-describedby with error id\n const ariaDescribedBy = [ariaDescribedByAttr, errorId, descriptionId].filter(Boolean).join(\" \") || undefined\n\n const controlProps = {\n \"ref\": inputRef,\n \"id\": inputId,\n \"name\": props.name,\n // Vue re-applies a present `value` key on every render, so an\n // uncontrolled field must not carry one (it would reset typed text)\n ...(props.value !== undefined ? { value: props.value } : {}),\n \"disabled\": props.disabled,\n \"readonly\": readOnly,\n // An explicit aria-invalid (e.g. from Field) wins over the computed state\n \"aria-invalid\": restAttrs[\"aria-invalid\"] ?? (invalid ? true : undefined),\n \"aria-describedby\": ariaDescribedBy,\n \"onInput\": handleInput,\n \"onFocus\": (evt: FocusEvent) => {\n focused.value = true\n callListeners(onFocusAttr, evt)\n },\n \"onBlur\": (evt: FocusEvent) => {\n focused.value = false\n callListeners(onBlurAttr, evt)\n },\n }\n // Uncontrolled: `vDefaultValue` sets the initial value (server markup,\n // hydration and later changes as in React)\n const initialValue = props.value === undefined ? props.defaultValue : undefined\n // The textarea's text content follows the controlled value, else\n // `default-value`, as React keeps a textarea's defaultValue\n const { value: _value, ...textareaControlProps } = controlProps as typeof controlProps & { value?: unknown }\n const textContent = String(props.value ?? props.defaultValue ?? \"\")\n\n const inside = props.labelPlacement === \"inside\"\n\n return h(\"div\", {\n \"class\": clsx(s.Root, className as string | undefined),\n \"data-label-placement\": inside ? \"inside\" : undefined,\n \"data-pill\": props.pill && !inside ? \"\" : undefined,\n }, [\n h(\n \"div\",\n {\n \"class\": clsx(s.FieldFootprint, { [s.HasValue!]: hasValue.value || !!startAdornment }),\n \"data-focused\": focused.value ? \"\" : undefined,\n \"data-has-value\": hasValue.value ? \"\" : undefined,\n \"data-invalid\": invalid ? \"\" : undefined,\n \"data-disabled\": props.disabled ? \"\" : undefined,\n \"data-readonly\": readOnly ? \"\" : undefined,\n \"data-multiline\": props.multiline ? \"\" : undefined,\n \"onMousedown\": handleContainerMouseDown,\n },\n [\n h(\"label\", { class: s.TypeableLabel, for: inputId }, [\n h(\"div\", { class: s.LabelPositioner }, [h(\"div\", { class: s.LabelText }, props.label)]),\n ]),\n startAdornment ? h(\"div\", { class: s.StartAdornment }, startAdornment) : null,\n props.multiline\n ? withDirectives(\n h(\n \"textarea\",\n mergeProps(textareaAttrs(restAttrs), {\n ...textareaControlProps,\n rows: props.rows,\n class: s.Textarea,\n textContent,\n }),\n ),\n [[vServerText, textContent]],\n )\n : withDirectives(\n h(\n \"input\",\n mergeProps(restAttrs, {\n ...controlProps,\n \"type\": effectiveType,\n \"class\": s.Input,\n \"onAnimationstart\": handleAnimationStart,\n \"data-lpignore\": props.allowAutofillExtensions ? undefined : true,\n \"data-1p-ignore\": props.allowAutofillExtensions ? undefined : true,\n }),\n ),\n [[vDefaultValue, initialValue]],\n ),\n endAdornment ? h(\"div\", { class: s.EndAdornment }, endAdornment) : null,\n showClearButton\n ? h(\"button\", { \"type\": \"button\", \"aria-label\": \"Clear input\", \"class\": s.ClearButton, \"onClick\": handleClear }, [h(X)])\n : null,\n showRevealButton\n ? h(\n \"button\",\n { \"type\": \"button\", \"aria-label\": revealed.value ? \"Hide\" : \"Show\", \"class\": s.RevealButton, \"onClick\": handleRevealToggle },\n [revealed.value ? h(EyeOff) : h(Eye)],\n )\n : null,\n ],\n ),\n props.errorMessage ? h(\"div\", { id: errorId, class: s.ErrorMessage, role: \"alert\" }, props.errorMessage) : null,\n description ? h(\"div\", { id: descriptionId, class: s.Description }, description) : null,\n ])\n }\n },\n})\n\ntype FloatingLabelInputOwnProps = InstanceType<typeof FloatingLabelInputComponent>[\"$props\"]\n\n/** FloatingLabelInput props plus the native <input> attributes that fall through to it, as in React. */\nexport type FloatingLabelInputProps = FloatingLabelInputOwnProps &\n Omit<InputHTMLAttributes, keyof FloatingLabelInputOwnProps>\n\n/** Text input whose label floats above the value, with optional reveal toggle and multiline mode. */\nexport const FloatingLabelInput = FloatingLabelInputComponent as typeof FloatingLabelInputComponent & {\n new (): { $props: FloatingLabelInputProps }\n}\n"]}
|
|
@@ -42,6 +42,10 @@ export const FloatingLabelSelect = defineComponent({
|
|
|
42
42
|
onClearClick: Function,
|
|
43
43
|
/** Called on pointer down, ArrowDown, ArrowUp and Space on the field (`@interact`) */
|
|
44
44
|
onInteract: Function,
|
|
45
|
+
/** Where the label rests once it floats: on the border, or inside the box with the value under it (always the rounded box). @default "border" */
|
|
46
|
+
labelPlacement: { type: String, default: "border" },
|
|
47
|
+
/** Pill shape. `false` takes the rounded box of the other fields. @default true */
|
|
48
|
+
pill: { type: Boolean, default: true },
|
|
45
49
|
},
|
|
46
50
|
setup(props, { attrs, slots, expose }) {
|
|
47
51
|
const generatedId = useId();
|
|
@@ -103,7 +107,12 @@ export const FloatingLabelSelect = defineComponent({
|
|
|
103
107
|
const showClearButton = !!props.onClearClick && selected && !disabled;
|
|
104
108
|
const ariaDescribedBy = [ariaDescribedByAttr, errorMessage ? errorId : undefined].filter(Boolean).join(" ") ||
|
|
105
109
|
undefined;
|
|
106
|
-
|
|
110
|
+
const inside = props.labelPlacement === "inside";
|
|
111
|
+
return h("div", {
|
|
112
|
+
"class": clsx(s.Root, className),
|
|
113
|
+
"data-label-placement": inside ? "inside" : undefined,
|
|
114
|
+
"data-pill": props.pill && !inside ? "" : undefined,
|
|
115
|
+
}, [
|
|
107
116
|
h("div", {
|
|
108
117
|
"ref": fieldRef,
|
|
109
118
|
"class": clsx(s.FieldFootprint, { [s.HasValue]: selected }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingLabelSelect.js","sourceRoot":"","sources":["../../../../src/components/FloatingLabelSelect/FloatingLabelSelect.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAAiB,MAAM,KAAK,CAAA;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,CAAC,MAAM,8EAA8E,CAAA;AAI5F,MAAM,aAAa,GAAG,CAAC,SAAkB,EAAE,KAAoB,EAAE,EAAE;IACjE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAC/D,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU;YAAG,QAAqB,CAAC,KAAK,CAAC,CAAA;IACnE,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC;IACjD,IAAI,EAAE,qBAAqB;IAC3B,YAAY,EAAE,KAAK;IACnB,KAAK,EAAE;QACL,wCAAwC;QACxC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;QACvC,+FAA+F;QAC/F,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;QAC3C,+CAA+C;QAC/C,YAAY,EAAE,MAAM;QACpB,sFAAsF;QACtF,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE;QAC9C,wEAAwE;QACxE,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;QAC3C,wDAAwD;QACxD,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;QACvC,oFAAoF;QACpF,YAAY,EAAE,QAAgC;QAC9C,sFAAsF;QACtF,UAAU,EAAE,QAAgC;KAC7C;IACD,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE;QACnC,MAAM,WAAW,GAAG,KAAK,EAAE,CAAA;QAC3B,MAAM,OAAO,GAAG,yBAAyB,WAAW,QAAQ,CAAA;QAC5D,MAAM,QAAQ,GAAG,UAAU,CAAqB,IAAI,CAAC,CAAA;QAErD,wEAAwE;QACxE,qEAAqE;QACrE,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QAEzF,MAAM,iBAAiB,GAAG,CAAC,GAAiB,EAAE,EAAE;YAC9C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ;gBAAE,OAAM;YAC9C,GAAG,CAAC,cAAc,EAAE,CAAA;YACpB,KAAK,CAAC,UAAU,EAAE,EAAE,CAAA;QACtB,CAAC,CAAA;QAED,MAAM,aAAa,GAAG,CAAC,GAAkB,EAAE,EAAE;YAC3C,uEAAuE;YACvE,uEAAuE;YACvE,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,aAAa,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO,CAAC;gBAAE,OAAM;YACxF,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;YACnC,oEAAoE;YACpE,oEAAoE;YACpE,IAAI,KAAK,CAAC,QAAQ,IAAI,GAAG,CAAC,gBAAgB;gBAAE,OAAM;YAElD,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC;gBAChB,KAAK,WAAW,CAAC;gBACjB,KAAK,SAAS,CAAC;gBACf,KAAK,GAAG,CAAC;gBACT,KAAK,OAAO;oBACV,2DAA2D;oBAC3D,sDAAsD;oBACtD,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,UAAU;wBAAE,MAAK;oBAClD,GAAG,CAAC,eAAe,EAAE,CAAA;oBACrB,GAAG,CAAC,cAAc,EAAE,CAAA;oBACpB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;wBACrB,KAAK,CAAC,UAAU,EAAE,CAAA;oBACpB,CAAC;yBAAM,CAAC;wBACN,4EAA4E;wBAC5E,CAAC;wBAAC,GAAG,CAAC,aAA6B,CAAC,KAAK,EAAE,CAAA;oBAC7C,CAAC;oBACD,MAAK;YACT,CAAC;QACH,CAAC,CAAA;QAED,MAAM,sBAAsB,GAAG,CAAC,GAAiB,EAAE,EAAE;YACnD,GAAG,CAAC,eAAe,EAAE,CAAA;QACvB,CAAC,CAAA;QAED,MAAM,gBAAgB,GAAG,CAAC,GAAe,EAAE,EAAE;YAC3C,GAAG,CAAC,eAAe,EAAE,CAAA;YACrB,GAAG,CAAC,cAAc,EAAE,CAAA;YACpB,KAAK,CAAC,YAAY,EAAE,EAAE,CAAA;QACxB,CAAC,CAAA;QAED,OAAO,GAAG,EAAE;YACV,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,KAAK,CAAA;YACxD,MAAM,EACJ,OAAO,EAAE,SAAS,EAClB,kBAAkB,EAAE,mBAAmB,EACvC,WAAW,EAAE,UAAU,EACvB,GAAG,SAAS,EACb,GAAG,KAAK,CAAA;YAET,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,YAAY,CAAA;YAE/C,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAA;YAErE,MAAM,eAAe,GACnB,CAAC,mBAAyC,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBACzG,SAAS,CAAA;YAEX,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,SAA+B,CAAC,EAAE,EAAE;gBACxE,CAAC,CACC,KAAK,EACL;oBACE,KAAK,EAAE,QAAQ;oBACf,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,QAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;oBAC5D,MAAM,EAAE,QAAQ;oBAChB,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC7B,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;oBAClC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;oBACxC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;oBAC1C,eAAe,EAAE,IAAI;oBACrB,eAAe,EAAE,SAAS;oBAC1B,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;oBAC1C,kBAAkB,EAAE,eAAe;oBACnC,eAAe,EAAE,QAAQ,IAAI,SAAS;oBACtC,eAAe,EAAE,iBAAiB;oBAClC,WAAW,EAAE,aAAa;oBAC1B,GAAG,SAAS;iBACb,EACD;oBACE,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE;wBACnC,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;qBACxF,CAAC;oBACF,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;oBACzE,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,gBAAgB,EAAE,EAAE;wBACtC,eAAe;4BACb,CAAC,CAAC,CAAC,CACC,MAAM,EACN;gCACE,YAAY,EAAE,iBAAiB;gCAC/B,OAAO,EAAE,CAAC,CAAC,KAAK;gCAChB,eAAe,EAAE,sBAAsB;gCACvC,SAAS,EAAE,gBAAgB;gCAC3B,OAAO,EAAE,WAAW;gCACpB,SAAS,EAAE,OAAO;gCAClB,MAAM,EAAE,KAAK;gCACb,SAAS,EAAE,IAAI;gCACf,MAAM,EAAE,IAAI;6BACb,EACD,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAC1B;4BACH,CAAC,CAAC,IAAI;wBACR,CAAC,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC;qBACvC,CAAC;iBACH,CACF;gBACD,2EAA2E;gBAC3E,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;aACtG,CAAC,CAAA;QACJ,CAAC,CAAA;IACH,CAAC;CACF,CAAC,CAAA","sourcesContent":["import clsx from \"clsx\"\nimport { defineComponent, h, shallowRef, useId, type PropType } from \"vue\"\nimport { Button } from \"../Button/index.js\"\nimport { Dropdown, X } from \"../Icon/index.js\"\nimport s from \"@plexui/styles/components/FloatingLabelSelect/FloatingLabelSelect.module.css\"\n\ntype Listener = (event: KeyboardEvent) => void\n\nconst callListeners = (listeners: unknown, event: KeyboardEvent) => {\n const list = Array.isArray(listeners) ? listeners : [listeners]\n for (const listener of list) {\n if (typeof listener === \"function\") (listener as Listener)(event)\n }\n}\n\n/**\n * Port of packages/ui/src/components/FloatingLabelSelect/FloatingLabelSelect.tsx.\n * A select trigger shell: `class` goes to the root, every other attribute\n * and listener to the `role=\"button\"` field, spread after the component's\n * own (so, as in React, a consumer `@pointerdown` replaces the built-in\n * one, while a consumer `@keydown` runs before the built-in handling).\n * `onClearClick` (`@clear-click`) and `onInteract` (`@interact`) are function\n * props, as in React: the clear button renders only when the first is set,\n * and without the second, the keys that open the field click it instead, so\n * a wrapping trigger (Select's `#trigger`) opens from the keyboard too.\n * A parent's ref resolves `$el` to the field, as React forwards its ref there.\n */\nexport const FloatingLabelSelect = defineComponent({\n name: \"FloatingLabelSelect\",\n inheritAttrs: false,\n props: {\n /** Label text for the floating label */\n label: { type: String, required: true },\n /** Whether a value is selected: floats the label and shows the default slot. @default false */\n selected: { type: Boolean, default: false },\n /** Error message to display below the field */\n errorMessage: String,\n /** Mark the field as invalid. @default false (or true if errorMessage is provided) */\n invalid: { type: Boolean, default: undefined },\n /** Disables the field visually and from interactions. @default false */\n disabled: { type: Boolean, default: false },\n /** Whether the attached list is open. @default false */\n open: { type: Boolean, default: false },\n /** Shows the clear button (when selected and enabled); called when it is clicked */\n onClearClick: Function as PropType<() => void>,\n /** Called on pointer down, ArrowDown, ArrowUp and Space on the field (`@interact`) */\n onInteract: Function as PropType<() => void>,\n },\n setup(props, { attrs, slots, expose }) {\n const generatedId = useId()\n const errorId = `floating-label-select-${generatedId}-error`\n const fieldRef = shallowRef<HTMLElement | null>(null)\n\n // React forwards its ref to the field: a wrapping trigger returns focus\n // to it and anchors to it, not to the root that also holds the error\n expose(Object.defineProperty({}, \"$el\", { enumerable: true, get: () => fieldRef.value }))\n\n const handlePointerDown = (evt: PointerEvent) => {\n if (evt.button === 2 || props.disabled) return\n evt.preventDefault()\n props.onInteract?.()\n }\n\n const handleKeyDown = (evt: KeyboardEvent) => {\n // Enter and Space on a nested control (the clear button) activate that\n // control: neither this handler nor a wrapping trigger's may take them\n if (evt.target !== evt.currentTarget && (evt.key === \" \" || evt.key === \"Enter\")) return\n callListeners(attrs.onKeydown, evt)\n // A handler that prevented the default (the caller's, or a wrapping\n // MenuTrigger's that opened its menu) cancels the built-in handling\n if (props.disabled || evt.defaultPrevented) return\n\n switch (evt.key) {\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \" \":\n case \"Enter\":\n // Enter activates the field only without onInteract, as it\n // would the button a wrapping trigger usually renders\n if (evt.key === \"Enter\" && props.onInteract) break\n evt.stopPropagation()\n evt.preventDefault()\n if (props.onInteract) {\n props.onInteract()\n } else {\n // A wrapping trigger (Select's `#trigger`, a PopoverTrigger) opens on click\n ;(evt.currentTarget as HTMLElement).click()\n }\n break\n }\n }\n\n const handleClearPointerDown = (evt: PointerEvent) => {\n evt.stopPropagation()\n }\n\n const handleClearClick = (evt: MouseEvent) => {\n evt.stopPropagation()\n evt.preventDefault()\n props.onClearClick?.()\n }\n\n return () => {\n const { selected, disabled, open, errorMessage } = props\n const {\n \"class\": className,\n \"aria-describedby\": ariaDescribedByAttr,\n \"onKeydown\": _onKeydown,\n ...restAttrs\n } = attrs\n\n const invalid = props.invalid ?? !!errorMessage\n\n const showClearButton = !!props.onClearClick && selected && !disabled\n\n const ariaDescribedBy =\n [ariaDescribedByAttr as string | undefined, errorMessage ? errorId : undefined].filter(Boolean).join(\" \") ||\n undefined\n\n return h(\"div\", { class: clsx(s.Root, className as string | undefined) }, [\n h(\n \"div\",\n {\n \"ref\": fieldRef,\n \"class\": clsx(s.FieldFootprint, { [s.HasValue!]: selected }),\n \"role\": \"button\",\n \"tabindex\": disabled ? -1 : 0,\n \"data-open\": open ? \"\" : undefined,\n \"data-invalid\": invalid ? \"\" : undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"aria-expanded\": open,\n \"aria-haspopup\": \"listbox\",\n \"aria-invalid\": invalid ? true : undefined,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-disabled\": disabled || undefined,\n \"onPointerdown\": handlePointerDown,\n \"onKeydown\": handleKeyDown,\n ...restAttrs,\n },\n [\n h(\"div\", { class: s.TypeableLabel }, [\n h(\"div\", { class: s.LabelPositioner }, [h(\"div\", { class: s.LabelText }, props.label)]),\n ]),\n h(\"span\", { class: s.Content }, selected ? slots.default?.() : undefined),\n h(\"div\", { class: s.IndicatorWrapper }, [\n showClearButton\n ? h(\n Button,\n {\n \"aria-label\": \"Clear selection\",\n \"class\": s.Clear,\n \"onPointerdown\": handleClearPointerDown,\n \"onClick\": handleClearClick,\n \"color\": \"secondary\",\n \"variant\": \"ghost\",\n \"size\": \"3xs\",\n \"uniform\": true,\n \"pill\": true,\n },\n { default: () => [h(X)] },\n )\n : null,\n h(Dropdown, { class: s.DropdownIcon }),\n ]),\n ],\n ),\n // Same plain line as FloatingLabelInput, so the two read alike on one form\n errorMessage ? h(\"div\", { id: errorId, class: s.ErrorMessage, role: \"alert\" }, [errorMessage]) : null,\n ])\n }\n },\n})\n\nexport type FloatingLabelSelectProps = InstanceType<typeof FloatingLabelSelect>[\"$props\"]\n"]}
|
|
1
|
+
{"version":3,"file":"FloatingLabelSelect.js","sourceRoot":"","sources":["../../../../src/components/FloatingLabelSelect/FloatingLabelSelect.ts"],"names":[],"mappings":"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","sourcesContent":["import clsx from \"clsx\"\nimport { defineComponent, h, shallowRef, useId, type PropType } from \"vue\"\nimport { Button } from \"../Button/index.js\"\nimport { Dropdown, X } from \"../Icon/index.js\"\nimport s from \"@plexui/styles/components/FloatingLabelSelect/FloatingLabelSelect.module.css\"\n\ntype Listener = (event: KeyboardEvent) => void\n\nconst callListeners = (listeners: unknown, event: KeyboardEvent) => {\n const list = Array.isArray(listeners) ? listeners : [listeners]\n for (const listener of list) {\n if (typeof listener === \"function\") (listener as Listener)(event)\n }\n}\n\n/**\n * Port of packages/ui/src/components/FloatingLabelSelect/FloatingLabelSelect.tsx.\n * A select trigger shell: `class` goes to the root, every other attribute\n * and listener to the `role=\"button\"` field, spread after the component's\n * own (so, as in React, a consumer `@pointerdown` replaces the built-in\n * one, while a consumer `@keydown` runs before the built-in handling).\n * `onClearClick` (`@clear-click`) and `onInteract` (`@interact`) are function\n * props, as in React: the clear button renders only when the first is set,\n * and without the second, the keys that open the field click it instead, so\n * a wrapping trigger (Select's `#trigger`) opens from the keyboard too.\n * A parent's ref resolves `$el` to the field, as React forwards its ref there.\n */\nexport const FloatingLabelSelect = defineComponent({\n name: \"FloatingLabelSelect\",\n inheritAttrs: false,\n props: {\n /** Label text for the floating label */\n label: { type: String, required: true },\n /** Whether a value is selected: floats the label and shows the default slot. @default false */\n selected: { type: Boolean, default: false },\n /** Error message to display below the field */\n errorMessage: String,\n /** Mark the field as invalid. @default false (or true if errorMessage is provided) */\n invalid: { type: Boolean, default: undefined },\n /** Disables the field visually and from interactions. @default false */\n disabled: { type: Boolean, default: false },\n /** Whether the attached list is open. @default false */\n open: { type: Boolean, default: false },\n /** Shows the clear button (when selected and enabled); called when it is clicked */\n onClearClick: Function as PropType<() => void>,\n /** Called on pointer down, ArrowDown, ArrowUp and Space on the field (`@interact`) */\n onInteract: Function as PropType<() => void>,\n /** Where the label rests once it floats: on the border, or inside the box with the value under it (always the rounded box). @default \"border\" */\n labelPlacement: { type: String as PropType<\"border\" | \"inside\">, default: \"border\" },\n /** Pill shape. `false` takes the rounded box of the other fields. @default true */\n pill: { type: Boolean, default: true },\n },\n setup(props, { attrs, slots, expose }) {\n const generatedId = useId()\n const errorId = `floating-label-select-${generatedId}-error`\n const fieldRef = shallowRef<HTMLElement | null>(null)\n\n // React forwards its ref to the field: a wrapping trigger returns focus\n // to it and anchors to it, not to the root that also holds the error\n expose(Object.defineProperty({}, \"$el\", { enumerable: true, get: () => fieldRef.value }))\n\n const handlePointerDown = (evt: PointerEvent) => {\n if (evt.button === 2 || props.disabled) return\n evt.preventDefault()\n props.onInteract?.()\n }\n\n const handleKeyDown = (evt: KeyboardEvent) => {\n // Enter and Space on a nested control (the clear button) activate that\n // control: neither this handler nor a wrapping trigger's may take them\n if (evt.target !== evt.currentTarget && (evt.key === \" \" || evt.key === \"Enter\")) return\n callListeners(attrs.onKeydown, evt)\n // A handler that prevented the default (the caller's, or a wrapping\n // MenuTrigger's that opened its menu) cancels the built-in handling\n if (props.disabled || evt.defaultPrevented) return\n\n switch (evt.key) {\n case \"ArrowDown\":\n case \"ArrowUp\":\n case \" \":\n case \"Enter\":\n // Enter activates the field only without onInteract, as it\n // would the button a wrapping trigger usually renders\n if (evt.key === \"Enter\" && props.onInteract) break\n evt.stopPropagation()\n evt.preventDefault()\n if (props.onInteract) {\n props.onInteract()\n } else {\n // A wrapping trigger (Select's `#trigger`, a PopoverTrigger) opens on click\n ;(evt.currentTarget as HTMLElement).click()\n }\n break\n }\n }\n\n const handleClearPointerDown = (evt: PointerEvent) => {\n evt.stopPropagation()\n }\n\n const handleClearClick = (evt: MouseEvent) => {\n evt.stopPropagation()\n evt.preventDefault()\n props.onClearClick?.()\n }\n\n return () => {\n const { selected, disabled, open, errorMessage } = props\n const {\n \"class\": className,\n \"aria-describedby\": ariaDescribedByAttr,\n \"onKeydown\": _onKeydown,\n ...restAttrs\n } = attrs\n\n const invalid = props.invalid ?? !!errorMessage\n\n const showClearButton = !!props.onClearClick && selected && !disabled\n\n const ariaDescribedBy =\n [ariaDescribedByAttr as string | undefined, errorMessage ? errorId : undefined].filter(Boolean).join(\" \") ||\n undefined\n\n const inside = props.labelPlacement === \"inside\"\n\n return h(\"div\", {\n \"class\": clsx(s.Root, className as string | undefined),\n \"data-label-placement\": inside ? \"inside\" : undefined,\n \"data-pill\": props.pill && !inside ? \"\" : undefined,\n }, [\n h(\n \"div\",\n {\n \"ref\": fieldRef,\n \"class\": clsx(s.FieldFootprint, { [s.HasValue!]: selected }),\n \"role\": \"button\",\n \"tabindex\": disabled ? -1 : 0,\n \"data-open\": open ? \"\" : undefined,\n \"data-invalid\": invalid ? \"\" : undefined,\n \"data-disabled\": disabled ? \"\" : undefined,\n \"aria-expanded\": open,\n \"aria-haspopup\": \"listbox\",\n \"aria-invalid\": invalid ? true : undefined,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-disabled\": disabled || undefined,\n \"onPointerdown\": handlePointerDown,\n \"onKeydown\": handleKeyDown,\n ...restAttrs,\n },\n [\n h(\"div\", { class: s.TypeableLabel }, [\n h(\"div\", { class: s.LabelPositioner }, [h(\"div\", { class: s.LabelText }, props.label)]),\n ]),\n h(\"span\", { class: s.Content }, selected ? slots.default?.() : undefined),\n h(\"div\", { class: s.IndicatorWrapper }, [\n showClearButton\n ? h(\n Button,\n {\n \"aria-label\": \"Clear selection\",\n \"class\": s.Clear,\n \"onPointerdown\": handleClearPointerDown,\n \"onClick\": handleClearClick,\n \"color\": \"secondary\",\n \"variant\": \"ghost\",\n \"size\": \"3xs\",\n \"uniform\": true,\n \"pill\": true,\n },\n { default: () => [h(X)] },\n )\n : null,\n h(Dropdown, { class: s.DropdownIcon }),\n ]),\n ],\n ),\n // Same plain line as FloatingLabelInput, so the two read alike on one form\n errorMessage ? h(\"div\", { id: errorId, class: s.ErrorMessage, role: \"alert\" }, [errorMessage]) : null,\n ])\n }\n },\n})\n\nexport type FloatingLabelSelectProps = InstanceType<typeof FloatingLabelSelect>[\"$props\"]\n"]}
|
|
@@ -28,10 +28,12 @@ declare const FieldComponent: import("vue").DefineComponent<import("vue").Extrac
|
|
|
28
28
|
type: BooleanConstructor;
|
|
29
29
|
default: boolean;
|
|
30
30
|
};
|
|
31
|
-
/** Layout direction of label and control. @default "vertical" */
|
|
32
|
-
orientation:
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
/** Layout direction of label and control. @default "horizontal" on a `row`, else "vertical" */
|
|
32
|
+
orientation: PropType<"vertical" | "horizontal">;
|
|
33
|
+
/** One line of a FieldGroup: label at the start, control at the end. @default false */
|
|
34
|
+
row: {
|
|
35
|
+
type: BooleanConstructor;
|
|
36
|
+
default: boolean;
|
|
35
37
|
};
|
|
36
38
|
/** Overrides the generated id set on the control and the label's `for`. A child's own `id` wins over both. */
|
|
37
39
|
id: StringConstructor;
|
|
@@ -58,10 +60,12 @@ declare const FieldComponent: import("vue").DefineComponent<import("vue").Extrac
|
|
|
58
60
|
type: BooleanConstructor;
|
|
59
61
|
default: boolean;
|
|
60
62
|
};
|
|
61
|
-
/** Layout direction of label and control. @default "vertical" */
|
|
62
|
-
orientation:
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
/** Layout direction of label and control. @default "horizontal" on a `row`, else "vertical" */
|
|
64
|
+
orientation: PropType<"vertical" | "horizontal">;
|
|
65
|
+
/** One line of a FieldGroup: label at the start, control at the end. @default false */
|
|
66
|
+
row: {
|
|
67
|
+
type: BooleanConstructor;
|
|
68
|
+
default: boolean;
|
|
65
69
|
};
|
|
66
70
|
/** Overrides the generated id set on the control and the label's `for`. A child's own `id` wins over both. */
|
|
67
71
|
id: StringConstructor;
|
|
@@ -69,7 +73,7 @@ declare const FieldComponent: import("vue").DefineComponent<import("vue").Extrac
|
|
|
69
73
|
opticallyAlign: PropType<"start" | "end">;
|
|
70
74
|
}>> & Readonly<{}>, {
|
|
71
75
|
required: boolean;
|
|
72
|
-
|
|
76
|
+
row: boolean;
|
|
73
77
|
}, SlotsType<{
|
|
74
78
|
/** The control. Read the props to render them yourself (React's render prop). */
|
|
75
79
|
default?: (fieldProps: FieldChildProps) => VNodeChild;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ClassValue } from "clsx";
|
|
2
|
+
import { type PropType, type SlotsType, type VNodeChild } from "vue";
|
|
3
|
+
declare const FieldGroupComponent: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
/** Heading over the block (or the `title` slot); it names the group */
|
|
5
|
+
title: StringConstructor;
|
|
6
|
+
/** Line under the title (or the `description` slot) */
|
|
7
|
+
description: StringConstructor;
|
|
8
|
+
/** Class for the block that holds the rows */
|
|
9
|
+
bodyClass: PropType<ClassValue>;
|
|
10
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
13
|
+
/** Heading over the block (or the `title` slot); it names the group */
|
|
14
|
+
title: StringConstructor;
|
|
15
|
+
/** Line under the title (or the `description` slot) */
|
|
16
|
+
description: StringConstructor;
|
|
17
|
+
/** Class for the block that holds the rows */
|
|
18
|
+
bodyClass: PropType<ClassValue>;
|
|
19
|
+
}>> & Readonly<{}>, {}, SlotsType<{
|
|
20
|
+
/** The rows: `Field row`, or rows of your own. */
|
|
21
|
+
default?: () => VNodeChild;
|
|
22
|
+
title?: () => VNodeChild;
|
|
23
|
+
description?: () => VNodeChild;
|
|
24
|
+
/** Content at the end of the header, such as a button */
|
|
25
|
+
action?: () => VNodeChild;
|
|
26
|
+
/** Content under the block, such as a note */
|
|
27
|
+
footer?: () => VNodeChild;
|
|
28
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
29
|
+
type FieldGroupOwnProps = InstanceType<typeof FieldGroupComponent>["$props"];
|
|
30
|
+
/** FieldGroup props; attributes reach the root element. */
|
|
31
|
+
export type FieldGroupProps = FieldGroupOwnProps & {
|
|
32
|
+
class?: ClassValue;
|
|
33
|
+
};
|
|
34
|
+
/** A titled block of rows: `Field row` lines with hairlines between them. */
|
|
35
|
+
export declare const FieldGroup: typeof FieldGroupComponent & {
|
|
36
|
+
new (): {
|
|
37
|
+
$props: FieldGroupProps;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FieldGroup, type FieldGroupProps } from "./FieldGroup.js";
|
|
@@ -57,6 +57,16 @@ declare const FloatingLabelInputComponent: import("vue").DefineComponent<import(
|
|
|
57
57
|
type: NumberConstructor;
|
|
58
58
|
default: number;
|
|
59
59
|
};
|
|
60
|
+
/** Where the label rests once it floats: on the border, or inside the box with the value under it (always the rounded box). @default "border" */
|
|
61
|
+
labelPlacement: {
|
|
62
|
+
type: PropType<"border" | "inside">;
|
|
63
|
+
default: string;
|
|
64
|
+
};
|
|
65
|
+
/** Pill shape. `false` takes the rounded box of the other fields. @default true */
|
|
66
|
+
pill: {
|
|
67
|
+
type: BooleanConstructor;
|
|
68
|
+
default: boolean;
|
|
69
|
+
};
|
|
60
70
|
id: StringConstructor;
|
|
61
71
|
name: StringConstructor;
|
|
62
72
|
type: {
|
|
@@ -129,6 +139,16 @@ declare const FloatingLabelInputComponent: import("vue").DefineComponent<import(
|
|
|
129
139
|
type: NumberConstructor;
|
|
130
140
|
default: number;
|
|
131
141
|
};
|
|
142
|
+
/** Where the label rests once it floats: on the border, or inside the box with the value under it (always the rounded box). @default "border" */
|
|
143
|
+
labelPlacement: {
|
|
144
|
+
type: PropType<"border" | "inside">;
|
|
145
|
+
default: string;
|
|
146
|
+
};
|
|
147
|
+
/** Pill shape. `false` takes the rounded box of the other fields. @default true */
|
|
148
|
+
pill: {
|
|
149
|
+
type: BooleanConstructor;
|
|
150
|
+
default: boolean;
|
|
151
|
+
};
|
|
132
152
|
id: StringConstructor;
|
|
133
153
|
name: StringConstructor;
|
|
134
154
|
type: {
|
|
@@ -153,12 +173,14 @@ declare const FloatingLabelInputComponent: import("vue").DefineComponent<import(
|
|
|
153
173
|
value: string | number;
|
|
154
174
|
defaultValue: string | number;
|
|
155
175
|
disabled: boolean;
|
|
176
|
+
pill: boolean;
|
|
156
177
|
readOnly: boolean;
|
|
157
178
|
readonly: boolean;
|
|
158
179
|
allowAutofillExtensions: boolean;
|
|
159
180
|
revealable: boolean;
|
|
160
181
|
multiline: boolean;
|
|
161
182
|
rows: number;
|
|
183
|
+
labelPlacement: "inside" | "border";
|
|
162
184
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
163
185
|
type FloatingLabelInputOwnProps = InstanceType<typeof FloatingLabelInputComponent>["$props"];
|
|
164
186
|
/** FloatingLabelInput props plus the native <input> attributes that fall through to it, as in React. */
|
|
@@ -43,6 +43,16 @@ export declare const FloatingLabelSelect: import("vue").DefineComponent<import("
|
|
|
43
43
|
onClearClick: PropType<() => void>;
|
|
44
44
|
/** Called on pointer down, ArrowDown, ArrowUp and Space on the field (`@interact`) */
|
|
45
45
|
onInteract: PropType<() => void>;
|
|
46
|
+
/** Where the label rests once it floats: on the border, or inside the box with the value under it (always the rounded box). @default "border" */
|
|
47
|
+
labelPlacement: {
|
|
48
|
+
type: PropType<"border" | "inside">;
|
|
49
|
+
default: string;
|
|
50
|
+
};
|
|
51
|
+
/** Pill shape. `false` takes the rounded box of the other fields. @default true */
|
|
52
|
+
pill: {
|
|
53
|
+
type: BooleanConstructor;
|
|
54
|
+
default: boolean;
|
|
55
|
+
};
|
|
46
56
|
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
47
57
|
[key: string]: any;
|
|
48
58
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
@@ -77,10 +87,22 @@ export declare const FloatingLabelSelect: import("vue").DefineComponent<import("
|
|
|
77
87
|
onClearClick: PropType<() => void>;
|
|
78
88
|
/** Called on pointer down, ArrowDown, ArrowUp and Space on the field (`@interact`) */
|
|
79
89
|
onInteract: PropType<() => void>;
|
|
90
|
+
/** Where the label rests once it floats: on the border, or inside the box with the value under it (always the rounded box). @default "border" */
|
|
91
|
+
labelPlacement: {
|
|
92
|
+
type: PropType<"border" | "inside">;
|
|
93
|
+
default: string;
|
|
94
|
+
};
|
|
95
|
+
/** Pill shape. `false` takes the rounded box of the other fields. @default true */
|
|
96
|
+
pill: {
|
|
97
|
+
type: BooleanConstructor;
|
|
98
|
+
default: boolean;
|
|
99
|
+
};
|
|
80
100
|
}>> & Readonly<{}>, {
|
|
81
101
|
invalid: boolean;
|
|
82
102
|
disabled: boolean;
|
|
83
103
|
open: boolean;
|
|
104
|
+
pill: boolean;
|
|
84
105
|
selected: boolean;
|
|
106
|
+
labelPlacement: "inside" | "border";
|
|
85
107
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
86
108
|
export type FloatingLabelSelectProps = InstanceType<typeof FloatingLabelSelect>["$props"];
|