@resee-movies/nuxt-ux 0.4.1 → 0.6.0

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.
Files changed (75) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +9 -2
  3. package/dist/runtime/components/Button.vue +15 -9
  4. package/dist/runtime/components/Button.vue.d.ts +2 -12
  5. package/dist/runtime/components/Card.vue.d.ts +1 -4
  6. package/dist/runtime/components/Dialog.vue.d.ts +1 -13
  7. package/dist/runtime/components/Drawer.vue.d.ts +1 -4
  8. package/dist/runtime/components/Heading.vue.d.ts +1 -4
  9. package/dist/runtime/components/Icon.vue +27 -15
  10. package/dist/runtime/components/Icon.vue.d.ts +4 -6
  11. package/dist/runtime/components/IconTextPair.vue +22 -19
  12. package/dist/runtime/components/IconTextPair.vue.d.ts +5 -12
  13. package/dist/runtime/components/Image.vue +1 -1
  14. package/dist/runtime/components/Image.vue.d.ts +1 -17
  15. package/dist/runtime/components/LayoutPageColumn.vue.d.ts +1 -4
  16. package/dist/runtime/components/LayoutPageContainer.vue +12 -2
  17. package/dist/runtime/components/LayoutPageContainer.vue.d.ts +4 -5
  18. package/dist/runtime/components/Lorem.vue.d.ts +1 -11
  19. package/dist/runtime/components/Menu.vue +28 -20
  20. package/dist/runtime/components/Menu.vue.d.ts +4 -7
  21. package/dist/runtime/components/Message.vue.d.ts +2 -2
  22. package/dist/runtime/components/NotificationContainer.vue +0 -1
  23. package/dist/runtime/components/ProgressBar.vue.d.ts +1 -5
  24. package/dist/runtime/components/ProgressSpinner.vue.d.ts +1 -3
  25. package/dist/runtime/components/Tag.vue.d.ts +1 -7
  26. package/dist/runtime/components/ToggleButton.vue +45 -0
  27. package/dist/runtime/components/ToggleButton.vue.d.ts +30 -0
  28. package/dist/runtime/components/form/Form.vue +79 -0
  29. package/dist/runtime/components/form/Form.vue.d.ts +35 -0
  30. package/dist/runtime/components/form/FormField.vue +96 -0
  31. package/dist/runtime/components/form/FormField.vue.d.ts +42 -0
  32. package/dist/runtime/components/form/FormFieldCheckbox.vue +56 -0
  33. package/dist/runtime/components/form/FormFieldCheckbox.vue.d.ts +17 -0
  34. package/dist/runtime/components/form/FormFieldSelect.vue +86 -0
  35. package/dist/runtime/components/form/FormFieldSelect.vue.d.ts +40 -0
  36. package/dist/runtime/components/form/FormFieldSelectButton.vue +76 -0
  37. package/dist/runtime/components/form/FormFieldSelectButton.vue.d.ts +16 -0
  38. package/dist/runtime/components/form/FormFieldText.vue +56 -0
  39. package/dist/runtime/components/form/FormFieldText.vue.d.ts +16 -0
  40. package/dist/runtime/components/form/FormFieldToggleSwitch.vue +47 -0
  41. package/dist/runtime/components/form/FormFieldToggleSwitch.vue.d.ts +15 -0
  42. package/dist/runtime/components/form/FormLabelInputPair.vue +42 -0
  43. package/dist/runtime/components/form/FormLabelInputPair.vue.d.ts +22 -0
  44. package/dist/runtime/components/form/FormSubmitButton.vue +26 -0
  45. package/dist/runtime/components/form/FormSubmitButton.vue.d.ts +8 -0
  46. package/dist/runtime/components/form/FormValidationMessage.vue +24 -0
  47. package/dist/runtime/components/form/FormValidationMessage.vue.d.ts +15 -0
  48. package/dist/runtime/components/form/element/FormElementSelectButton.vue +110 -0
  49. package/dist/runtime/components/form/element/FormElementSelectButton.vue.d.ts +33 -0
  50. package/dist/runtime/components/form/element/FormElementSelectOptions.vue +256 -0
  51. package/dist/runtime/components/form/element/FormElementSelectOptions.vue.d.ts +24 -0
  52. package/dist/runtime/composables/use-load-image.js +1 -0
  53. package/dist/runtime/composables/use-resee-ux.d.ts +25 -0
  54. package/dist/runtime/composables/use-resee-ux.js +23 -0
  55. package/dist/runtime/constants.d.ts +3 -0
  56. package/dist/runtime/constants.js +3 -0
  57. package/dist/runtime/server/plugins/teleport-targets.d.ts +3 -0
  58. package/dist/runtime/server/plugins/teleport-targets.js +6 -0
  59. package/dist/runtime/theme/css/brand/form.css +3 -0
  60. package/dist/runtime/theme/css/brand/menu.css +1 -0
  61. package/dist/runtime/theme/css/brand/mobile.css +1 -0
  62. package/dist/runtime/theme/css/brand/transition.css +1 -1
  63. package/dist/runtime/theme/css/brand/utilities.css +1 -1
  64. package/dist/runtime/theme/css/styles.css +1 -1
  65. package/dist/runtime/types/form.d.ts +23 -0
  66. package/dist/runtime/types/form.js +0 -0
  67. package/dist/runtime/utils/dom.d.ts +9 -0
  68. package/dist/runtime/utils/dom.js +25 -0
  69. package/dist/runtime/utils/form.d.ts +34 -0
  70. package/dist/runtime/utils/form.js +34 -0
  71. package/dist/runtime/utils/string.d.ts +6 -0
  72. package/dist/runtime/utils/string.js +3 -0
  73. package/dist/runtime/utils/validation.d.ts +21 -0
  74. package/dist/runtime/utils/validation.js +56 -0
  75. package/package.json +26 -24
@@ -0,0 +1,24 @@
1
+ import { type SelectProps as PrimeSelectProps } from 'primevue/select';
2
+ export interface FormElementSelectOptionsProps extends Omit<PrimeSelectProps, 'inputId' | 'labelId' | 'optionGroupLabel' | 'optionGroupChildren'> {
3
+ inputId?: string;
4
+ labelId?: string;
5
+ multiple?: boolean;
6
+ readonly?: boolean;
7
+ showOptionFilter?: boolean;
8
+ ariaDescribedby?: string;
9
+ selectionLimit?: string | number;
10
+ }
11
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormElementSelectOptionsProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormElementSelectOptionsProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
12
+ option?: (props: {
13
+ option: any;
14
+ selected: any;
15
+ index: any;
16
+ }) => any;
17
+ }>;
18
+ declare const _default: typeof __VLS_export;
19
+ export default _default;
20
+ type __VLS_WithSlots<T, S> = T & {
21
+ new (): {
22
+ $slots: S;
23
+ };
24
+ };
@@ -52,6 +52,7 @@ export function useLoadImage(source, config = {}) {
52
52
  src.value = sourceUnwrapped;
53
53
  }
54
54
  }
55
+ loading.value = true;
55
56
  key.value = sourceUnwrapped;
56
57
  return;
57
58
  }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Provides the ability to manage runtime configuration of the ReSee UX
3
+ * module.
4
+ */
5
+ export declare function useReseeUx(): {
6
+ locale: {
7
+ validation: {
8
+ required: string;
9
+ invalidEmail: string;
10
+ invalidUrl: string;
11
+ tooFewChars: string;
12
+ tooManyChars: string;
13
+ tooFewOptions: string;
14
+ tooManyOptions: string;
15
+ };
16
+ form: {
17
+ submitButtonLabel: string;
18
+ filterPlaceholder: string;
19
+ filterNoResults: string;
20
+ noOptionsAvailable: string;
21
+ selectAllOptions: string;
22
+ numOptionsSelected: string;
23
+ };
24
+ };
25
+ };
@@ -0,0 +1,23 @@
1
+ import { reactive } from "vue";
2
+ const Localization = reactive({
3
+ validation: {
4
+ required: "Required",
5
+ invalidEmail: "A valid email address is required",
6
+ invalidUrl: "A valid URL (https://...) is required",
7
+ tooFewChars: "Must have at least {count} character(s)",
8
+ tooManyChars: "Cannot have more than {count} character(s)",
9
+ tooFewOptions: "Must select at least {count} option(s)",
10
+ tooManyOptions: "Cannot select more than {count} option(s)"
11
+ },
12
+ form: {
13
+ submitButtonLabel: "Submit",
14
+ filterPlaceholder: "Search",
15
+ filterNoResults: "No Results Found",
16
+ noOptionsAvailable: "No Options Available",
17
+ selectAllOptions: "Select All",
18
+ numOptionsSelected: "{count} Item(s) Selected"
19
+ }
20
+ });
21
+ export function useReseeUx() {
22
+ return { locale: Localization };
23
+ }
@@ -4,3 +4,6 @@ import type { HintedString, StyleStatusLevel } from './types/index.js';
4
4
  * the application.
5
5
  */
6
6
  export declare const StatusLevelIcons: Record<HintedString<StyleStatusLevel>, string>;
7
+ export declare const TeleportId = "#resee-ux-teleport";
8
+ export declare const OverflowHiddenClass = "p-overflow-hidden";
9
+ export declare const ScrollbarWidthPropName = "--p-scrollbar-width";
@@ -7,3 +7,6 @@ export const StatusLevelIcons = {
7
7
  default: "i-ph-info",
8
8
  inverted: "i-ph-info"
9
9
  };
10
+ export const TeleportId = "#resee-ux-teleport";
11
+ export const OverflowHiddenClass = "p-overflow-hidden";
12
+ export const ScrollbarWidthPropName = "--p-scrollbar-width";
@@ -0,0 +1,3 @@
1
+ import type { NitroAppPlugin } from 'nitropack';
2
+ declare const _default: NitroAppPlugin;
3
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import { TeleportId } from "../../constants.js";
2
+ export default (function(nitroApp) {
3
+ nitroApp.hooks.hook("render:html", (html) => {
4
+ html.body.push(`<div id="${TeleportId.replace("#", "")}" />`);
5
+ });
6
+ });
@@ -0,0 +1,3 @@
1
+ @layer components{.input-label{display:block;-webkit-user-select:none;-moz-user-select:none;user-select:none}.input-label.required:after{color:var(--color-danger);content:"*";display:inline-block;margin-inline-start:--spacing(1)}.input-label.disabled{cursor:not-allowed;opacity:.6}.input-label-pair{display:flex;flex-direction:column;gap:--spacing(1);margin-block-end:--spacing(1)}.input-label-pair.label-after,.input-label-pair.label-before{align-items:center;flex-direction:row;gap:--spacing(3)}.input-label-pair.label-after .input-label,.input-label-pair.label-below .input-label{order:2}.input-validation{color:var(--color-danger);font-size:var(--text-sm);height:0;line-clamp:2}.input-field{display:flex;flex-direction:column}.input-control{flex-grow:1;padding:--spacing(2) --spacing(3)}.input-control::-moz-placeholder{color:var(--color-global-foreground-accent)}.input-control .placeholder,.input-control::placeholder{color:var(--color-global-foreground-accent)}.input-group{align-items:center;display:flex}.input-group.input-group-loading{cursor:wait}.input-group .input-group-addon{color:var(--color-global-foreground-accent);padding:0 --spacing(2)}.input-group button.input-group-addon{cursor:pointer}.input-group .input-control{outline:none}.input-control:where(:not(.input-group .input-control)),.input-group{background-color:var(--color-global-background);border-radius:--spacing(1);cursor:pointer;outline:solid 2px var(--color-background-scale-e);overflow:clip;transition:color,background-color,outline-color,box-shadow;transition-duration:calc(var(--default-transition-duration)*2);width:100%}.input-control:where(:not(.input-group .input-control)):where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control)))),.input-group:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group)){cursor:default}.input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control))))):where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control))))))),.input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group))):where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group))))){cursor:not-allowed;opacity:.6}.input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control))))):not(:where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control)))))))):focus-within,.input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control))))):not(:where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control)))))))):hover,.input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group))):not(:where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group)))))):focus-within,.input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group))):not(:where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group)))))):hover{outline-color:var(--color-global-foreground-accent)}.input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control))))):not(:where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control)))))))):focus-within,.input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group))):not(:where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group)))))):focus-within{box-shadow:var(--shadow-heavy)}.input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control))))):not(:where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-control:where(:not(.input-group .input-control)):not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-control:where(:not(.input-group .input-control)))))))):not(:has(>input[type=checkbox]),.input-button-bar):focus-within,.input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group))):not(:where(.disabled,:disabled:not(.p-hidden-accessible input),:is(.disabled .input-group:not(:where(.readonly,[readonly]:not(.p-hidden-accessible input),:is(.readonly .input-group)))))):not(:has(>input[type=checkbox]),.input-button-bar):focus-within{background-color:var(--color-background-scale-b)}.input-group:where(:has(input[type=checkbox])){flex-shrink:0;height:1.5rem;position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:1.5rem}
2
+
3
+ /* !important is to overwrite what gets attached to i-* icons in the utility layer */.input-group:where(:has(input[type=checkbox])) span[class^=i-],.input-group:where(:has(input[type=checkbox])) svg{display:block!important;font-size:1rem;height:1rem!important;line-height:1;margin-left:.25rem;width:1rem!important}.input-group:where(:has(input[type=checkbox])) input{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:100%;inset:0;opacity:0;position:absolute;z-index:10}.input-group:where(:has(input[type=checkbox])) input:not(:disabled,[readonly]){cursor:pointer}.input-group:where(:has(input[type=checkbox])).toggle-switch{border-radius:1rem;width:2.5rem}.input-group:where(:has(input[type=checkbox])).toggle-switch:has(:checked) .slider:before{background-color:var(--color-global-foreground);transform:translateX(1rem)}.input-group:where(:has(input[type=checkbox])).toggle-switch .slider{border-radius:1rem;inset:0;position:absolute}.input-group:where(:has(input[type=checkbox])).toggle-switch .slider:before{background-color:var(--color-background-scale-d);border-radius:var(--radius-full);box-shadow:var(--shadow-md);content:"";height:1rem;left:.25rem;position:absolute;top:.25rem;transition:transform,background-color;transition-duration:var(--default-transition-duration);width:1rem}.input-menu .input-control,.input-menu .input-group{background-color:transparent}.input-menu .input-group:where(:has(input[type=checkbox])){height:1.2rem;width:1.2rem}.input-menu .input-group:where(:has(input[type=checkbox])) span[class^=i-],.input-menu .input-group:where(:has(input[type=checkbox])) svg{margin-left:.1rem;margin-top:-.1rem}[aria-disabled=true] .input-menu .input-group:where(:has(input[type=checkbox])):focus-within,[aria-disabled=true] .input-menu .input-group:where(:has(input[type=checkbox])):hover{outline-color:var(--color-background-scale-e)!important}[aria-disabled=true] .input-menu .input-group:where(:has(input[type=checkbox])):focus-within input,[aria-disabled=true] .input-menu .input-group:where(:has(input[type=checkbox])):hover input{cursor:not-allowed!important}.input-menu-header{align-items:center;display:flex;gap:--spacing(2)}.input-menu-header .input-menu-filter{align-items:center;color:var(--color-global-foreground-accent);display:flex;flex-grow:1;transition:color var(--default-transition-duration) var(--default-transition-timing-function)}.input-menu-header .input-menu-filter input{flex-grow:1;outline:none;padding:--spacing(.5) 0}.input-menu-header .input-menu-filter input::-moz-placeholder{color:var(--color-global-foreground-accent)}.input-menu-header .input-menu-filter input::placeholder{color:var(--color-global-foreground-accent)}.input-menu-header .input-menu-filter:focus-within{color:var(--color-global-foreground)}.input-button-bar{gap:--spacing(.5);padding:--spacing(.5);width:-moz-fit-content;width:fit-content}.input-button-bar button{cursor:pointer;padding:--spacing(1.5) --spacing(2);transition:background-color var(--default-transition-duration) var(--default-transition-timing-function)}.input-button-bar button[aria-pressed=true]{background-color:var(--color-background-scale-f)}.input-button-bar button:where(.readonly button){cursor:default}.input-button-bar button:disabled:not(:where(.readonly button)){cursor:not-allowed;opacity:.6}.input-button-bar button:not(:disabled,:where(.readonly button),[aria-pressed=true]):focus-visible,.input-button-bar button:not(:disabled,:where(.readonly button),[aria-pressed=true]):hover{background-color:var(--color-background-scale-b)}.input-button-bar button:first-child{border-bottom-left-radius:var(--radius-sm);border-top-left-radius:var(--radius-sm)}.input-button-bar button:last-child{border-bottom-right-radius:var(--radius-sm);border-top-right-radius:var(--radius-sm)}}
@@ -0,0 +1 @@
1
+ @layer components{.menu{background-color:var(--color-background-scale-a);border:1px solid var(--color-global-background-accent);border-radius:var(--radius-md);box-shadow:var(--shadow-heavy);display:flex;flex-direction:column;margin-block:--spacing(1);max-width:--spacing(80);padding:--spacing(1)}.menu .menu-list{max-height:14rem;overflow-y:auto;@apply styled-scroll}.menu li[role=separator]{border-bottom:1px solid var(--color-global-background-accent);margin-block:--spacing(1)}.menu li[role=none]{font-weight:var(--font-weight-semibold);padding:--spacing(1) --spacing(2);-webkit-user-select:none;-moz-user-select:none;user-select:none}.menu li[role=menuitem],.menu li[role=option]{border-radius:var(--radius-md);cursor:pointer;transition:background-color;transition-duration:var(--default-transition-duration);-webkit-user-select:none;-moz-user-select:none;user-select:none}.menu li[role=menuitem]>:only-child:not(:has(>a:only-child)),.menu li[role=option]>:only-child:not(:has(>a:only-child)){display:block;padding:--spacing(1) --spacing(2)}.menu li[role=menuitem]>:only-child:has(>a:only-child)>a,.menu li[role=option]>:only-child:has(>a:only-child)>a{display:block;padding:--spacing(1) --spacing(2)}.menu li[role=menuitem]:has(>:nth-child(2)),.menu li[role=option]:has(>:nth-child(2)){align-items:center;display:flex;gap:--spacing(2);padding:--spacing(1) --spacing(2)}.menu li[role=menuitem][aria-disabled=true],.menu li[role=option][aria-disabled=true]{color:var(--color-global-foreground-accent);cursor:not-allowed}.menu li:is([role=menuitem],[role=option])[data-p-focused=true]:not([aria-disabled=true]),.menu ul:not(:focus) li:is([role=menuitem],[role=option]):not([aria-disabled=true]):hover{background-color:var(--color-background-scale-c)}.menu .menu-prefix{border-bottom:1px solid var(--color-global-background-accent);margin-bottom:--spacing(1);padding:0 --spacing(2) --spacing(1)}.menu .menu-suffix{border-top:1px solid var(--color-global-background-accent);margin-top:--spacing(1);padding:--spacing(1) --spacing(2) 0}}
@@ -0,0 +1 @@
1
+ @layer utilities{#resee-ux-teleport:has(:first-child:not(script,link)){@variant max-sm{inset:0;position:fixed;z-index:1100;@apply occlude-background}}@variant max-sm{.menu{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:0;border-left-width:0;border-right-width:0;bottom:0;box-shadow:var(--shadow-heavy-top);font-size:var(--text-lg);inset-inline-start:0!important;left:0;margin-block:0;margin-top:0!important;max-height:70vh;max-width:unset;min-width:0!important;right:0;top:unset!important}.menu .menu-list{max-height:unset!important}}}
@@ -1 +1 @@
1
- @layer base{.fade-enter-active,.fade-leave-active,.grow-x-enter-active,.grow-x-leave-active,.grow-y-enter-active,.grow-y-leave-active{transition:opacity;transition-duration:calc(var(--default-transition-duration)*2);transition-timing-function:var(--default-transition-timing-function)}.fade-enter-from,.fade-leave-to,.grow-x-enter-from,.grow-x-leave-to,.grow-y-enter-from,.grow-y-leave-to{opacity:0}@supports (interpolate-size:allow-keywords){.grow-y-enter-active,.grow-y-leave-active{interpolate-size:allow-keywords;height:-moz-max-content;height:max-content;overflow-y:clip;transition:opacity,height;transition-duration:calc(var(--default-transition-duration)*2);transition-timing-function:var(--default-transition-timing-function)}.grow-y-enter-from,.grow-y-leave-to{height:0}.grow-x-enter-active,.grow-x-leave-active{interpolate-size:allow-keywords;overflow-x:clip;transition:opacity,width;transition-duration:calc(var(--default-transition-duration)*2);transition-timing-function:var(--default-transition-timing-function);width:auto}.grow-x-enter-from,.grow-x-leave-to{width:0}}.slide-in-bottom-enter-active,.slide-in-bottom-leave-active,.slide-in-left-enter-active,.slide-in-left-leave-active,.slide-in-right-enter-active,.slide-in-right-leave-active,.slide-in-top-enter-active,.slide-in-top-leave-active{transition-duration:calc(var(--default-transition-duration)*3);transition-property:transform;transition-timing-function:var(--default-transition-timing-function)}.slide-in-left-enter-from,.slide-in-left-leave-to{transform:translateX(-100%)}.slide-in-right-enter-from,.slide-in-right-leave-to{transform:translateX(100%)}.slide-in-top-enter-from,.slide-in-top-leave-to{transform:translateY(-100%)}.slide-in-bottom-enter-from,.slide-in-bottom-leave-to{transform:translateY(100%)}.scale-enter-active,.scale-leave-active{transition-duration:calc(var(--default-transition-duration)*2);transition-property:opacity,transform;transition-timing-function:var(--default-transition-timing-function)}.scale-enter-from,.scale-leave-to{opacity:0;transform:scale(.85)}}
1
+ @layer base{:root{--fade-transition-duration:calc(var(--default-transition-duration)*2);--grow-transition-duration:calc(var(--default-transition-duration)*2);--slide-transition-duration:calc(var(--default-transition-duration)*3);--scale-transition-duration:calc(var(--default-transition-duration)*2)}.fade-enter-active,.fade-leave-active,.grow-x-enter-active,.grow-x-leave-active,.grow-y-enter-active,.grow-y-leave-active{transition:opacity;transition-duration:var(--fade-transition-duration);transition-timing-function:var(--default-transition-timing-function)}.fade-enter-from,.fade-leave-to,.grow-x-enter-from,.grow-x-leave-to,.grow-y-enter-from,.grow-y-leave-to{opacity:0}@supports (interpolate-size:allow-keywords){.grow-y-enter-active,.grow-y-leave-active{interpolate-size:allow-keywords;height:-moz-max-content;height:max-content;overflow-y:clip;transition:opacity,height;transition-duration:var(--grow-transition-duration);transition-timing-function:var(--default-transition-timing-function)}.grow-y-enter-from,.grow-y-leave-to{height:0!important}.grow-x-enter-active,.grow-x-leave-active{interpolate-size:allow-keywords;overflow-x:clip;transition:opacity,width;transition-duration:var(--grow-transition-duration);transition-timing-function:var(--default-transition-timing-function);width:-moz-fit-content;width:fit-content}.grow-x-enter-from,.grow-x-leave-to{width:0!important}}.slide-in-bottom-enter-active,.slide-in-bottom-leave-active,.slide-in-left-enter-active,.slide-in-left-leave-active,.slide-in-right-enter-active,.slide-in-right-leave-active,.slide-in-top-enter-active,.slide-in-top-leave-active{transition-duration:var(--slide-transition-duration);transition-property:transform;transition-timing-function:var(--default-transition-timing-function)}.slide-in-left-enter-from,.slide-in-left-leave-to{transform:translateX(-100%)}.slide-in-right-enter-from,.slide-in-right-leave-to{transform:translateX(100%)}.slide-in-top-enter-from,.slide-in-top-leave-to{transform:translateY(-100%)}.slide-in-bottom-enter-from,.slide-in-bottom-leave-to{transform:translateY(100%)}.scale-enter-active,.scale-leave-active{transition-duration:var(--scale-transition-duration);transition-property:opacity,transform;transition-timing-function:var(--default-transition-timing-function)}.scale-enter-from,.scale-leave-to{opacity:0;transform:scale(.85)}}
@@ -1 +1 @@
1
- @utility content-zero-width{content:var(--zero-width-space)}@utility occlude-background{backdrop-filter:blur(var(--blur-xs));background-color:--alpha(var(--color-black)/60%);transition-duration:calc(var(--default-transition-duration)*3);transition-property:background-color,backdrop-filter;&:has(>[class*=-enter-from],>[class*=-leave-active],>[class*=-leave-to]){backdrop-filter:blur(0);background-color:transparent}}
1
+ @utility content-zero-width{content:var(--zero-width-space)}@utility occlude-background{backdrop-filter:blur(var(--blur-xs));background-color:--alpha(var(--color-black)/60%);transition-duration:calc(var(--default-transition-duration)*3);transition-property:background-color,backdrop-filter;&:has(>[class*=-enter-from],>[class*=-leave-active],>[class*=-leave-to]){backdrop-filter:blur(0);background-color:transparent}}@utility styled-scroll{scrollbar-color:color-mix(in srgb-linear,transparent 75%,var(--color-global-foreground-accent)) transparent;scrollbar-width:thin;transition:scrollbar-color .4s ease-out;&:focus-visible,&:focus-within,&:hover{scrollbar-color:var(--color-global-foreground-accent) transparent;transition-delay:0s}}
@@ -1 +1 @@
1
- @import "./brand/anchor.css";@import "./brand/application.css";@import "./brand/button.css";@import "./brand/gradient.css";@import "./brand/status.css";@import "./brand/theme.css";@import "./brand/tooltip.css";@import "./brand/transition.css";@import "./brand/typography.css";@import "./brand/utilities.css";
1
+ @import "./brand/anchor.css";@import "./brand/application.css";@import "./brand/button.css";@import "./brand/form.css";@import "./brand/gradient.css";@import "./brand/menu.css";@import "./brand/mobile.css";@import "./brand/status.css";@import "./brand/theme.css";@import "./brand/tooltip.css";@import "./brand/transition.css";@import "./brand/typography.css";@import "./brand/utilities.css";
@@ -0,0 +1,23 @@
1
+ import type { FormSubmitEvent as PrimeFormSubmitEvent } from '@primevue/forms/form';
2
+ import type { Ref } from 'vue';
3
+ /**
4
+ * An object which carries the current values of a form's input fields.
5
+ */
6
+ export type FormValues = Record<string, any>;
7
+ /**
8
+ * The object provided by a form, conveying stateful information, that can be
9
+ * injected into descendent components.
10
+ */
11
+ export interface FormInstance {
12
+ hasSubmitted: Ref<boolean>;
13
+ isSubmitting: Ref<boolean>;
14
+ isDisabled: Ref<boolean>;
15
+ }
16
+ /**
17
+ * The event argument of a Form's `onsubmit` callback.
18
+ */
19
+ export type FormSubmitEvent<T extends FormValues = FormValues> = PrimeFormSubmitEvent<T>;
20
+ /**
21
+ * The `onsubmit` callback method of a Form.
22
+ */
23
+ export type FormSubmitHandler<T extends FormValues = FormValues> = (event: FormSubmitEvent<T>) => void | Promise<void>;
File without changes
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Blocks the body from being able to scroll in the same way that Primevue does
3
+ * internally, but with the added functionality of returning the method that can
4
+ * be used to perform the unblock. If the body has already been scroll-blocked by
5
+ * something else (say, this is being trigger by a menu that is being used inside
6
+ * a drawer), then the returned method is a noop.
7
+ */
8
+ export declare function blockBodyScroll(): () => void;
9
+ export declare function unblockBodyScroll(): void;
@@ -0,0 +1,25 @@
1
+ import { blockBodyScroll as block, unblockBodyScroll as unblock } from "@primeuix/utils/dom";
2
+ import { OverflowHiddenClass, ScrollbarWidthPropName } from "../constants.js";
3
+ export function blockBodyScroll() {
4
+ try {
5
+ if (!document.body.classList.contains(OverflowHiddenClass)) {
6
+ block({
7
+ className: OverflowHiddenClass,
8
+ variableName: ScrollbarWidthPropName
9
+ });
10
+ return () => unblockBodyScroll();
11
+ }
12
+ } catch {
13
+ }
14
+ return () => {
15
+ };
16
+ }
17
+ export function unblockBodyScroll() {
18
+ try {
19
+ unblock({
20
+ className: OverflowHiddenClass,
21
+ variableName: ScrollbarWidthPropName
22
+ });
23
+ } catch {
24
+ }
25
+ }
@@ -0,0 +1,34 @@
1
+ import type { FormFieldState } from '@primevue/forms';
2
+ import { type InjectionKey } from 'vue';
3
+ import type { FormInstance, FormValues } from '../types/form.js';
4
+ /**
5
+ * The injection key for acquiring a {@link FormInstance} object within the
6
+ * descendant component of a Form. Consider using {@link injectFormInstance}
7
+ * instead.
8
+ */
9
+ export declare const FormSymbol: InjectionKey<FormInstance>;
10
+ /**
11
+ * Helper method to create a new stateful object for a Form. You shouldn't ever
12
+ * need to use this directly.
13
+ *
14
+ * @private
15
+ */
16
+ export declare function createFormInstance(): FormInstance;
17
+ /**
18
+ * Provides the object that a Form uses to convey stateful information to the
19
+ * DI registry. You shouldn't ever need to use this directly.
20
+ *
21
+ * @private
22
+ */
23
+ export declare function provideFormInstance(): FormInstance;
24
+ /**
25
+ * Injects the stateful object provided by an ancestor Form instance. If not
26
+ * available, a dummy state object is generated.
27
+ */
28
+ export declare function injectFormInstance(): FormInstance;
29
+ /**
30
+ * Takes a Primevue Form's `states` object, and extracts the current values
31
+ * of each named property. In doing so, it will deref proxies, and create
32
+ * shallow clones of any arrays/objects it encounters.
33
+ */
34
+ export declare function getValuesFromFormState<T extends FormValues = FormValues>(state: Record<string, FormFieldState>): T;
@@ -0,0 +1,34 @@
1
+ import { isObjectLike } from "@resee-movies/utilities/objects/is-object-like";
2
+ import { inject, provide, ref, toRaw, toValue } from "vue";
3
+ export const FormSymbol = Symbol("form");
4
+ export function createFormInstance() {
5
+ return {
6
+ hasSubmitted: ref(false),
7
+ isSubmitting: ref(false),
8
+ isDisabled: ref(false)
9
+ };
10
+ }
11
+ export function provideFormInstance() {
12
+ const instance = createFormInstance();
13
+ provide(FormSymbol, instance);
14
+ return instance;
15
+ }
16
+ export function injectFormInstance() {
17
+ return inject(FormSymbol, () => createFormInstance(), true);
18
+ }
19
+ export function getValuesFromFormState(state) {
20
+ const result = {};
21
+ for (const [key, value] of Object.entries(state)) {
22
+ const rawValue = toRaw(toValue(value.value));
23
+ let processed;
24
+ if (Array.isArray(rawValue)) {
25
+ processed = Array.from(rawValue);
26
+ } else if (isObjectLike(rawValue)) {
27
+ processed = { ...rawValue };
28
+ } else {
29
+ processed = rawValue;
30
+ }
31
+ Object.defineProperty(result, key, { value: processed, enumerable: true });
32
+ }
33
+ return result;
34
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Takes a string and replaces all substrings which match the form `{PROPERTY}`,
3
+ * where "PROPERTY" is a key of the provided `placeholders` object, with the value
4
+ * at that key.
5
+ */
6
+ export declare function swapStringPlaceholders(target: string, placeholders?: Record<string, unknown>): string;
@@ -0,0 +1,3 @@
1
+ export function swapStringPlaceholders(target, placeholders) {
2
+ return placeholders ? target.replace(/\{\s*(\w+?)\s*}/g, (_, token) => String(placeholders[token] || "")) : target;
3
+ }
@@ -0,0 +1,21 @@
1
+ import * as z from 'zod/mini';
2
+ export declare function toValidationError(str: string, placeholders?: Record<string, string | number>): {
3
+ error: string;
4
+ };
5
+ export type BooleanInputRequirements = {
6
+ required?: boolean;
7
+ };
8
+ export declare function createBooleanValidator(requirements: BooleanInputRequirements): z.ZodMiniBoolean<unknown> | undefined;
9
+ export type TextInputRequirements = {
10
+ required?: boolean;
11
+ type?: 'text' | 'email' | 'url';
12
+ minLength?: string | number;
13
+ maxLength?: string | number;
14
+ };
15
+ export declare function createTextValidator(requirements: TextInputRequirements): z.ZodMiniString<string> | z.ZodMiniUnion<readonly [z.ZodMiniNull, z.ZodMiniString<string>]>;
16
+ export type ListInputRequirements = {
17
+ required?: boolean;
18
+ minRequired?: string | number;
19
+ maxRequired?: string | number;
20
+ };
21
+ export declare function createListValidator(requirements: ListInputRequirements): z.ZodMiniArray<z.ZodMiniUnknown> | z.ZodMiniUnion<readonly [z.ZodMiniNull, z.ZodMiniArray<z.ZodMiniUnknown>]>;
@@ -0,0 +1,56 @@
1
+ import { toInteger } from "@resee-movies/utilities/numbers/to-integer";
2
+ import * as z from "zod/mini";
3
+ import { useReseeUx } from "../composables/use-resee-ux.js";
4
+ import { swapStringPlaceholders } from "./string.js";
5
+ export function toValidationError(str, placeholders) {
6
+ return { error: swapStringPlaceholders(str, placeholders) };
7
+ }
8
+ export function createBooleanValidator(requirements) {
9
+ const { locale } = useReseeUx();
10
+ return requirements.required ? z.coerce.boolean().check(z.refine((val) => val === true, toValidationError(locale.validation.required))) : void 0;
11
+ }
12
+ export function createTextValidator(requirements) {
13
+ const { locale } = useReseeUx();
14
+ const checkFns = [];
15
+ if (requirements.required) {
16
+ checkFns.push(z.minLength(1, toValidationError(locale.validation.required)));
17
+ }
18
+ if (requirements.type === "email") {
19
+ checkFns.push(z.email(toValidationError(locale.validation.invalidEmail)));
20
+ } else if (requirements.type === "url") {
21
+ checkFns.push(z.url(toValidationError(locale.validation.invalidUrl)));
22
+ } else {
23
+ const minLength = toInteger(requirements.minLength);
24
+ const maxLength = toInteger(requirements.maxLength);
25
+ if (minLength) {
26
+ checkFns.push(
27
+ z.minLength(minLength, toValidationError(locale.validation.tooFewChars, { count: minLength }))
28
+ );
29
+ }
30
+ if (maxLength) {
31
+ checkFns.push(
32
+ z.maxLength(maxLength, toValidationError(locale.validation.tooManyChars, { count: maxLength }))
33
+ );
34
+ }
35
+ }
36
+ const stringSchema = z.string(toValidationError(locale.validation.required)).check(z.trim(), ...checkFns);
37
+ return requirements.required ? stringSchema : z.union([z.null(), stringSchema]);
38
+ }
39
+ export function createListValidator(requirements) {
40
+ const { locale } = useReseeUx();
41
+ const checkFns = [];
42
+ const minRequired = toInteger(requirements.minRequired) || (requirements.required ? 1 : void 0);
43
+ const maxRequired = toInteger(requirements.maxRequired);
44
+ if (minRequired) {
45
+ checkFns.push(
46
+ z.minLength(minRequired, toValidationError(locale.validation.tooFewOptions, { count: minRequired }))
47
+ );
48
+ }
49
+ if (maxRequired) {
50
+ checkFns.push(
51
+ z.maxLength(maxRequired, toValidationError(locale.validation.tooManyOptions, { count: maxRequired }))
52
+ );
53
+ }
54
+ const arraySchema = z.array(z.unknown(), toValidationError(locale.validation.required)).check(...checkFns);
55
+ return requirements.required ? arraySchema : z.union([z.null(), arraySchema]);
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@resee-movies/nuxt-ux",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "The next-gen user experience library for ReSee Movies - currently in development. ",
5
5
  "repository": {
6
6
  "url": "https://github.com/ReSee-Movies/nuxt-ux.git"
@@ -36,8 +36,8 @@
36
36
  ],
37
37
  "scripts": {
38
38
  "dev": "npm run dev:prepare && nuxi dev playground",
39
+ "dev:preview": "npm run dev:build && nuxi preview playground",
39
40
  "dev:build": "nuxi build playground",
40
- "dev:preview": "nuxi preview playground",
41
41
  "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
42
42
  "prepare": "nuxt-module-build prepare && nuxt-module-build build",
43
43
  "release": "dotenv release-it --",
@@ -48,40 +48,42 @@
48
48
  "test:coverage": "vitest run --coverage"
49
49
  },
50
50
  "devDependencies": {
51
- "@nuxt/devtools": "^2.6.5",
52
- "@nuxt/eslint": "^1.9.0",
53
- "@nuxt/eslint-config": "^1.9.0",
51
+ "@nuxt/devtools": "^3.1.1",
52
+ "@nuxt/eslint": "^1.11.0",
53
+ "@nuxt/eslint-config": "^1.11.0",
54
54
  "@nuxt/kit": "^4.1.3",
55
55
  "@nuxt/module-builder": "^1.0.2",
56
56
  "@nuxt/schema": "^4.1.3",
57
- "@nuxt/test-utils": "^3.19.2",
58
- "@release-it/conventional-changelog": "^10.0.1",
59
- "@types/node": "^22.18.8",
57
+ "@nuxt/test-utils": "^3.20.1",
58
+ "@release-it/conventional-changelog": "^10.0.2",
59
+ "@types/node": "^24.10.1",
60
60
  "@vitest/coverage-v8": "^3.2.4",
61
- "@vue/language-server": "^3.1.0",
62
61
  "@vue/test-utils": "^2.4.6",
63
- "dotenv-cli": "^10.0.0",
64
- "eslint": "^9.36.0",
65
- "happy-dom": "^18.0.1",
66
- "nuxt": "^4.1.2",
67
- "release-it": "^19.0.5",
62
+ "dotenv-cli": "^11.0.0",
63
+ "eslint": "^9.39.1",
64
+ "happy-dom": "^20.0.11",
65
+ "nuxt": "^4.2.1",
66
+ "release-it": "^19.0.6",
68
67
  "typescript": "^5.9.3",
68
+ "vite-plugin-devtools-json": "^1.0.0",
69
69
  "vitest": "^3.2.4",
70
- "vue-tsc": "^3.1.0"
70
+ "vue-tsc": "^3.1.5"
71
71
  },
72
72
  "dependencies": {
73
73
  "@egoist/tailwindcss-icons": "^1.9.0",
74
74
  "@iconify-json/ph": "^1.2.2",
75
- "@iconify-json/simple-icons": "^1.2.53",
76
- "@iconify-json/solar": "^1.2.4",
77
- "@nuxt/fonts": "^0.11.4",
75
+ "@iconify-json/simple-icons": "^1.2.61",
76
+ "@iconify-json/solar": "^1.2.5",
77
+ "@nuxt/fonts": "^0.12.1",
78
78
  "@primeuix/utils": "^0.6.1",
79
- "@primevue/nuxt-module": "^4.4.0",
79
+ "@primevue/forms": "^4.5.1",
80
+ "@primevue/nuxt-module": "^4.5.1",
80
81
  "@resee-movies/utilities": "^0.10.0",
81
- "@tailwindcss/postcss": "^4.1.14",
82
- "@tailwindcss/vite": "^4.1.14",
83
- "@vueuse/core": "^13.9.0",
84
- "primevue": "^4.4.0",
85
- "tailwindcss": "^4.1.14"
82
+ "@tailwindcss/postcss": "^4.1.17",
83
+ "@tailwindcss/vite": "^4.1.17",
84
+ "@vueuse/core": "^14.1.0",
85
+ "primevue": "^4.5.1",
86
+ "tailwindcss": "^4.1.17",
87
+ "zod": "^4.1.13"
86
88
  }
87
89
  }