vueless 0.0.488 → 0.0.490

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.
@@ -0,0 +1,200 @@
1
+ import type { Meta, StoryFn } from "@storybook/vue3";
2
+ import { getArgTypes, getSlotNames, getSlotsFragment } from "../../utils/storybook.ts";
3
+
4
+ import UDatePicker from "../../ui.form-date-picker/UDatePicker.vue";
5
+ import UIcon from "../../ui.image-icon/UIcon.vue";
6
+ import URow from "../../ui.container-row/URow.vue";
7
+
8
+ import type { UDatePickerProps } from "../types.ts";
9
+
10
+ interface DefaultUDatePickerArgs extends UDatePickerProps {
11
+ slotTemplate?: string;
12
+ }
13
+
14
+ interface EnumUDatePickerArgs extends UDatePickerProps {
15
+ slotTemplate?: string;
16
+ enum: "size";
17
+ }
18
+
19
+ /**
20
+ * The `UDatePicker` component. | [View on GitHub](https://github.com/vuelessjs/vueless/tree/main/src/ui.form-date-picker)
21
+ */
22
+ export default {
23
+ id: "3170",
24
+ title: "Form Inputs & Controls / Date Picker",
25
+ component: UDatePicker,
26
+ args: {
27
+ label: "Label",
28
+ modelValue: null,
29
+ },
30
+ argTypes: {
31
+ ...getArgTypes(UDatePicker.__name),
32
+ },
33
+ parameters: {
34
+ docs: {
35
+ story: {
36
+ height: "480px",
37
+ },
38
+ },
39
+ },
40
+ } as Meta;
41
+
42
+ const DefaultTemplate: StoryFn<DefaultUDatePickerArgs> = (args: DefaultUDatePickerArgs) => ({
43
+ components: { UDatePicker, UIcon },
44
+ setup() {
45
+ const slots = getSlotNames(UDatePicker.__name);
46
+
47
+ return { args, slots };
48
+ },
49
+ template: `
50
+ <UDatePicker open-direction-y="bottom" v-bind="args" v-model="args.modelValue">
51
+ ${args.slotTemplate || getSlotsFragment("")}
52
+ </UDatePicker>
53
+
54
+ <div class="mt-4">
55
+ {{ args.modelValue }}
56
+ </div>
57
+ `,
58
+ });
59
+
60
+ const EnumVariantTemplate: StoryFn<EnumUDatePickerArgs> = (
61
+ args: EnumUDatePickerArgs,
62
+ { argTypes },
63
+ ) => ({
64
+ components: { UDatePicker, URow },
65
+ setup() {
66
+ return {
67
+ args,
68
+ options: argTypes?.[args.enum]?.options,
69
+ };
70
+ },
71
+ template: `
72
+ <URow>
73
+ <UDatePicker
74
+ v-for="(option, index) in options"
75
+ open-direction-y="bottom"
76
+ :key="index"
77
+ v-bind="args"
78
+ :[args.enum]="option"
79
+ :label="option"
80
+ />
81
+ </URow>
82
+ `,
83
+ });
84
+
85
+ const OpenDirectionTemplate: StoryFn<DefaultUDatePickerArgs> = (args: DefaultUDatePickerArgs) => ({
86
+ components: { UDatePicker, URow },
87
+ setup() {
88
+ return {
89
+ args,
90
+ };
91
+ },
92
+ template: `
93
+ <URow class="!flex-col">
94
+ <UDatePicker
95
+ class="w-full"
96
+ open-direction-y="top"
97
+ open-direction-x="left"
98
+ v-bind="args"
99
+ v-model="args.modelValue"
100
+ label="Top Left"
101
+ />
102
+ <UDatePicker
103
+ class="w-full"
104
+ open-direction-y="top"
105
+ open-direction-x="right"
106
+ v-bind="args"
107
+ v-model="args.modelValue"
108
+ label="Top Right"
109
+ />
110
+ <UDatePicker
111
+ class="w-full"
112
+ open-direction-y="bottom"
113
+ open-direction-x="left"
114
+ v-bind="args"
115
+ v-model="args.modelValue"
116
+ label="Bottom Left"
117
+ />
118
+ <UDatePicker
119
+ class="w-full"
120
+ open-direction-y="bottom"
121
+ open-direction-x="right"
122
+ v-bind="args"
123
+ v-model="args.modelValue"
124
+ label="Bottom Right"
125
+ />
126
+ </URow>
127
+ `,
128
+ });
129
+
130
+ export const Default = DefaultTemplate.bind({});
131
+ Default.args = { modelValue: new Date() };
132
+
133
+ export const Sizes = EnumVariantTemplate.bind({});
134
+ Sizes.args = { enum: "size", label: "" };
135
+
136
+ export const OpenDirection = OpenDirectionTemplate.bind({});
137
+ OpenDirection.args = {};
138
+
139
+ export const Description = DefaultTemplate.bind({});
140
+ Description.args = { description: "some description" };
141
+
142
+ export const Disabled = DefaultTemplate.bind({});
143
+ Disabled.args = { disabled: true };
144
+
145
+ export const Error = DefaultTemplate.bind({});
146
+ Error.args = { error: "some error" };
147
+
148
+ export const Placeholder = DefaultTemplate.bind({});
149
+ Placeholder.args = { placeholder: "some placeholder" };
150
+
151
+ export const DateFormat = DefaultTemplate.bind({});
152
+ DateFormat.args = { dateFormat: "d.m.Y", userDateFormat: "d.m.Y", modelValue: "28.06.2024" };
153
+
154
+ export const Timepicker = DefaultTemplate.bind({});
155
+ Timepicker.args = {
156
+ timepicker: true,
157
+ modelValue: new Date(2024, 2, 14, 12, 24, 14),
158
+ userDateFormat: "j F, Y - H:i:S",
159
+ };
160
+
161
+ export const MinMax = DefaultTemplate.bind({});
162
+ MinMax.args = {
163
+ minDate: new Date(2022, 2, 22),
164
+ maxDate: new Date(2022, 2, 26),
165
+ modelValue: new Date(2022, 2, 24),
166
+ };
167
+
168
+ export const LeftIcon = DefaultTemplate.bind({});
169
+ LeftIcon.args = {
170
+ leftIcon: "star",
171
+ };
172
+
173
+ export const RightIcon = DefaultTemplate.bind({});
174
+ RightIcon.args = {
175
+ rightIcon: "star",
176
+ };
177
+
178
+ export const LeftIconSlot = DefaultTemplate.bind({});
179
+ LeftIconSlot.args = {
180
+ slotTemplate: `
181
+ <template #left-icon>
182
+ <UIcon
183
+ name="archive"
184
+ color="red"
185
+ />
186
+ </template>
187
+ `,
188
+ };
189
+
190
+ export const RightIconSlot = DefaultTemplate.bind({});
191
+ RightIconSlot.args = {
192
+ slotTemplate: `
193
+ <template #right-icon>
194
+ <UIcon
195
+ name="archive"
196
+ color="red"
197
+ />
198
+ </template>
199
+ `,
200
+ };
@@ -0,0 +1,119 @@
1
+ import defaultConfig from "./config.ts";
2
+
3
+ export type Config = Partial<typeof defaultConfig>;
4
+
5
+ export interface UDatePickerProps {
6
+ /**
7
+ * Calendar value (JavaScript Date object or string formatted in given `dateFormat` or object when `range` enabled).
8
+ */
9
+ modelValue: Date | string;
10
+
11
+ /**
12
+ * Datepicker label.
13
+ */
14
+ label?: string;
15
+
16
+ /**
17
+ * Datepicker label placement.
18
+ * @values top, topInside, topWithDesc, left, right
19
+ */
20
+ labelAlign?: "top" | "topInside" | "topWithDesc" | "left" | "right";
21
+
22
+ /**
23
+ * Datepicker placeholder.
24
+ */
25
+ placeholder?: string;
26
+
27
+ /**
28
+ * Datepicker description.
29
+ */
30
+ description?: string;
31
+
32
+ /**
33
+ * Datepicker error message.
34
+ */
35
+ error?: string;
36
+
37
+ /**
38
+ * Datepicker size.
39
+ * @values sm, md, lg
40
+ */
41
+ size?: "sm" | "md" | "lg";
42
+
43
+ /**
44
+ * Datepicker open direction on x-axis.
45
+ * @values auto, left, right
46
+ */
47
+ openDirectionX?: "auto" | "left" | "right";
48
+
49
+ /**
50
+ * Datepicker open direction on y-axis.
51
+ * @values auto, top, bottom
52
+ */
53
+ openDirectionY?: "auto" | "top" | "bottom";
54
+
55
+ /**
56
+ * Show timepicker.
57
+ */
58
+ timepicker?: boolean;
59
+
60
+ /**
61
+ * Date string format.
62
+ */
63
+ dateFormat?: string | undefined;
64
+
65
+ /**
66
+ * Same as date format, but used when timepicker is enabled.
67
+ */
68
+ dateTimeFormat?: string;
69
+
70
+ /**
71
+ * User-friendly date format (it will be shown in UI).
72
+ */
73
+ userDateFormat?: string;
74
+
75
+ /**
76
+ * Same as user format, but used when timepicker is enabled.
77
+ */
78
+ userDateTimeFormat?: string;
79
+
80
+ /**
81
+ * Min date (JavaScript Date object or string formatted in given `dateFormat`).
82
+ */
83
+ minDate?: string | Date | undefined;
84
+
85
+ /**
86
+ * Max date (JavaScript Date object or string formatted in given `dateFormat`).
87
+ */
88
+ maxDate?: string | Date | undefined;
89
+
90
+ /**
91
+ * Left icon name.
92
+ */
93
+ leftIcon?: string;
94
+
95
+ /**
96
+ * Right icon name.
97
+ */
98
+ rightIcon?: string;
99
+
100
+ /**
101
+ * Make datepicker disabled.
102
+ */
103
+ disabled?: boolean;
104
+
105
+ /**
106
+ * Unique element id.
107
+ */
108
+ id?: string;
109
+
110
+ /**
111
+ * Component config object.
112
+ */
113
+ config?: Config;
114
+
115
+ /**
116
+ * Data-test attribute for automated testing.
117
+ */
118
+ dataTest?: string;
119
+ }
@@ -0,0 +1,47 @@
1
+ import { computed, watchEffect, type Ref } from "vue";
2
+ import { merge } from "lodash-es";
3
+ import useUI from "../composables/useUI.ts";
4
+
5
+ import defaultConfig from "./config.ts";
6
+ import { Direction } from "../composables/useAutoPosition.ts";
7
+
8
+ import type { UseAttrs } from "../types.ts";
9
+ import type { UDatePickerProps, Config } from "./types.ts";
10
+ import type { Config as UCalendarConfig } from "../ui.form-calendar/types.ts";
11
+
12
+ interface DatePickerState {
13
+ isTop: Ref<boolean>;
14
+ isRight: Ref<boolean>;
15
+ }
16
+
17
+ export default function useAttrs(
18
+ props: UDatePickerProps,
19
+ { isTop, isRight }: DatePickerState,
20
+ ): UseAttrs<Config> {
21
+ const { config, getKeysAttrs, hasSlotContent } = useUI(defaultConfig, () => props.config);
22
+
23
+ const mutatedProps = computed(() => ({
24
+ openDirectionY: isTop.value ? Direction.Top : Direction.Bottom,
25
+ openDirectionX: isRight.value ? Direction.Right : Direction.Left,
26
+ error: Boolean(props.error),
27
+ description: Boolean(props.description),
28
+ }));
29
+
30
+ const keysAttrs = getKeysAttrs(mutatedProps);
31
+
32
+ /* Merging DatePicker's i18n translations into Calendar's i18n translations. */
33
+ watchEffect(() => {
34
+ const calendarAttrs = keysAttrs.calendarAttrs as Ref<{ config: UCalendarConfig }>;
35
+ const calendarConfig = calendarAttrs.value.config || {};
36
+
37
+ if (!calendarConfig.i18n || props.config?.i18n) {
38
+ calendarAttrs.value.config.i18n = merge(calendarConfig.i18n, config.value.i18n);
39
+ }
40
+ });
41
+
42
+ return {
43
+ config,
44
+ ...keysAttrs,
45
+ hasSlotContent,
46
+ };
47
+ }
@@ -127,21 +127,12 @@ const emit = defineEmits([
127
127
  const { config, iconAttrs } = useAttrs(props);
128
128
 
129
129
  const generatedIcons = computed(() => {
130
- /**
131
- * Use nuxt assets folders to include icons in final build.
132
- * TODO: Find another way to include icons in build
133
- */
134
- if (isSSR) {
135
- return (
136
- Object.entries(
137
- import.meta.glob(`/assets/.vueless/icons/**/*.svg`, { eager: true, query: "?component" }),
138
- ) || []
139
- );
140
- }
141
-
142
130
  return (
143
131
  Object.entries(
144
- import.meta.glob(`../assets/icons/**/*.svg`, { eager: true, query: "?component" }),
132
+ import.meta.glob(`/node_modules/.cache/vueless/assets/icons/**/*.svg`, {
133
+ eager: true,
134
+ query: "?component",
135
+ }),
145
136
  ) || []
146
137
  );
147
138
  });
@@ -185,8 +176,8 @@ const dynamicComponent = computed(() => {
185
176
  return import.meta.env.PROD
186
177
  ? await getIcon([name])
187
178
  : isSSR
188
- ? import(/* @vite-ignore */ `node_modules/vueless/assets/icons/${name}.svg?component`)
189
- : import(/* @vite-ignore */ `../assets/icons/${name}.svg?component`);
179
+ ? import(/* @vite-ignore */ `node_modules/.cache/vueless/assets/icons/${name}.svg?component`)
180
+ : import(/* @vite-ignore */ `/node_modules/.cache/vueless/assets/icons/${name}.svg?component`);
190
181
  },
191
182
  "@material-symbols": async () => {
192
183
  return import.meta.env.PROD
@@ -50,43 +50,41 @@ const { loaderAttrs, ellipseAttrs, config } = useAttrs(props);
50
50
  </script>
51
51
 
52
52
  <style scoped lang="postcss">
53
- .vueless-loader-ellipse {
54
- &:nth-child(1) {
55
- animation: ellipse-1 0.6s infinite;
56
- }
53
+ .vueless-loader-ellipse:nth-child(1) {
54
+ animation: ellipse-1 0.6s infinite;
55
+ }
57
56
 
58
- &:nth-child(4) {
59
- animation: ellipse-3 0.6s infinite;
60
- }
57
+ .vueless-loader-ellipse:nth-child(4) {
58
+ animation: ellipse-3 0.6s infinite;
59
+ }
61
60
 
62
- &-sm {
63
- &:nth-child(2) {
64
- animation: ellipse-2-sm 0.6s infinite;
65
- }
61
+ .vueless-loader-ellipse-sm {
62
+ &:nth-child(2) {
63
+ animation: ellipse-2-sm 0.6s infinite;
64
+ }
66
65
 
67
- &:nth-child(3) {
68
- animation: ellipse-2-sm 0.6s infinite;
69
- }
66
+ &:nth-child(3) {
67
+ animation: ellipse-2-sm 0.6s infinite;
70
68
  }
69
+ }
71
70
 
72
- &-md {
73
- &:nth-child(2) {
74
- animation: ellipse-2-md 0.6s infinite;
75
- }
71
+ .vueless-loader-ellipse-md {
72
+ &:nth-child(2) {
73
+ animation: ellipse-2-md 0.6s infinite;
74
+ }
76
75
 
77
- &:nth-child(3) {
78
- animation: ellipse-2-md 0.6s infinite;
79
- }
76
+ &:nth-child(3) {
77
+ animation: ellipse-2-md 0.6s infinite;
80
78
  }
79
+ }
81
80
 
82
- &-lg {
83
- &:nth-child(2) {
84
- animation: ellipse-2-lg 0.6s infinite;
85
- }
81
+ .vueless-loader-ellipse-lg {
82
+ &:nth-child(2) {
83
+ animation: ellipse-2-lg 0.6s infinite;
84
+ }
86
85
 
87
- &:nth-child(3) {
88
- animation: ellipse-2-lg 0.6s infinite;
89
- }
86
+ &:nth-child(3) {
87
+ animation: ellipse-2-lg 0.6s infinite;
90
88
  }
91
89
  }
92
90
 
@@ -18,8 +18,8 @@ import { getDirFiles, getDefaultConfigJson, merge } from "./helper.js";
18
18
  import { CACHE_PATH, VUELESS_CONFIG_FILE_NAME } from "../../constants.js";
19
19
 
20
20
  const ICONS_DIR = "assets/icons";
21
- const NUXT_ASSETS_DIR = path.join(process.cwd(), "assets/.vueless/icons");
22
- const DEFAULT_ICONS_DIR = path.join(process.cwd(), `src/${ICONS_DIR}`);
21
+ const DEFAULT_ICONS_DIR = path.join(process.cwd(), `node_modules/vueless/${ICONS_DIR}`);
22
+ const DEFAULT_ICONS_LOCAL_DIR = path.join(process.cwd(), `src/${ICONS_DIR}`);
23
23
  const CACHED_ICONS_DIR = path.join(process.cwd(), `${CACHE_PATH}/${ICONS_DIR}`);
24
24
  const ICON_CONFIG_PATH = "ui.image-icon/config.ts";
25
25
  const ICON_COMPONENT_NAME = "UIcon";
@@ -33,21 +33,31 @@ let isVuelessIconsMode = false;
33
33
  let cachedIconsDir = CACHED_ICONS_DIR;
34
34
 
35
35
  // perform icons copy magick... ✨
36
- export async function copyIcons({ mode = "", env, debug, targetFiles = [], isNuxt } = {}) {
36
+ export async function copyIcons({ mode = "", env, debug, targetFiles = [] } = {}) {
37
37
  isDebug = debug || false;
38
38
  isVuelessEnv = env === "vueless";
39
39
  isDefaultMode = mode === "";
40
40
  isStorybookMode = mode === "storybook";
41
41
  isVuelessIconsMode = mode === "vuelessIcons";
42
42
 
43
- if (isVuelessIconsMode && isVuelessEnv) cachedIconsDir = DEFAULT_ICONS_DIR;
43
+ /* Copy icons which using in vueless components to the cache (vueless env only). */
44
+ if (isVuelessEnv && fs.existsSync(DEFAULT_ICONS_LOCAL_DIR)) {
45
+ await cp(DEFAULT_ICONS_LOCAL_DIR, CACHED_ICONS_DIR, { recursive: true });
46
+ }
47
+
48
+ /* Copy icons which using in vueless components to the cache. */
49
+ if (!isVuelessEnv && fs.existsSync(DEFAULT_ICONS_DIR)) {
50
+ await cp(DEFAULT_ICONS_DIR, CACHED_ICONS_DIR, { recursive: true });
51
+ }
52
+
53
+ if (isVuelessIconsMode && isVuelessEnv) cachedIconsDir = DEFAULT_ICONS_LOCAL_DIR;
44
54
  if (isStorybookMode && isVuelessEnv) cachedIconsDir = CACHED_ICONS_DIR;
45
55
 
46
56
  if (isStorybookMode) {
47
57
  const storybookStoriesJs = await getDirFiles("src", STORYBOOK_STORY_EXTENSIONS[0]);
48
58
  const storybookStoriesTs = await getDirFiles("src", STORYBOOK_STORY_EXTENSIONS[1]);
49
59
 
50
- findAndCopyIcons([...storybookStoriesJs.flat(), ...storybookStoriesTs.flat()]);
60
+ findAndCopyIcons([...storybookStoriesJs, ...storybookStoriesTs]);
51
61
  }
52
62
 
53
63
  if (isVuelessIconsMode || isDefaultMode || isStorybookMode) {
@@ -69,23 +79,13 @@ export async function copyIcons({ mode = "", env, debug, targetFiles = [], isNux
69
79
  `${VUELESS_CONFIG_FILE_NAME}.ts`,
70
80
  ]);
71
81
  }
72
-
73
- if (isNuxt) {
74
- await cp(CACHED_ICONS_DIR, NUXT_ASSETS_DIR, {
75
- recursive: true,
76
- });
77
- }
78
82
  }
79
83
 
80
- export async function removeIcons({ debug, isNuxt }) {
84
+ export async function removeIcons({ debug }) {
81
85
  if (!fs.existsSync(cachedIconsDir)) return;
82
86
 
83
87
  await rm(cachedIconsDir, { recursive: true, force: true });
84
88
 
85
- if (isNuxt) {
86
- await rm(NUXT_ASSETS_DIR, { recursive: true, force: true });
87
- }
88
-
89
89
  if (debug) {
90
90
  console.log("Dynamically copied icons was successfully removed.");
91
91
  }
@@ -166,6 +166,13 @@ function findAndCopyIcons(files) {
166
166
  function copyFile(name) {
167
167
  name = name.toLowerCase();
168
168
 
169
+ const iconNameRegex = /^[a-z0-9_-]+$/;
170
+
171
+ /* Filter irrelevant icon name cases. */
172
+ if (!iconNameRegex.test(name)) {
173
+ return;
174
+ }
175
+
169
176
  const library = defaults.library;
170
177
  const weight = defaults.weight;
171
178
  const style = defaults.style;