vueless 0.0.176 → 0.0.178

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.
@@ -12,25 +12,57 @@ import defaultConfig from "./configs/default.config?raw"
12
12
  <Controls of={stories.Default} />
13
13
  <Stories of={stories} />
14
14
 
15
- ## Control loader
16
- You can control loader state using *useLoaderRendering* composable.
15
+ ## Using loader
16
+ To control the loader state in Vue components use `useLoaderTop` composable.
17
+
18
+ The loader uses queue of resources and will be shown until at least one item is present in a queue.
17
19
 
18
20
  <Source code={`
19
21
  import { useLoaderTop } from "vueless";
20
22
 
21
23
  const {
22
- loaderTopOn,
23
- loaderTopOff,
24
- addRequestUrl,
25
- removeRequestUrl
24
+ isLoading,
25
+ loaderTopOn,
26
+ loaderTopOff,
27
+ requestQueue,
28
+ componentRequestQueue,
29
+ setComponentRequestQueue,
30
+ removeComponentRequestQueue
26
31
  } = useLoaderTop();
32
+
33
+ // get loader state
34
+ console.log(isLoading.value);
35
+
36
+ // show loader (add resource into queue)
37
+ loaderTopOn("/transactions");
38
+
39
+ // hide loader (remove resource from queue)
40
+ loaderTopOff("/transactions");
41
+
42
+ // get current resource array
43
+ console.log(requestQueue.value);
44
+
45
+ // get current resource array for component relayed loaders (UTable)
46
+ console.log(componentRequestQueue.value);
47
+
48
+ // add resource into component related loader queue
49
+ setComponentRequestQueue("/transactions");
50
+
51
+ // remove resource from component related loader queue
52
+ removeComponentRequestQueue("/transactions");
27
53
  `} language="jsx" dark />
28
54
 
29
- ## Control outside a component
30
- You can control loader state outside vue components using the following methods.
55
+ ## Using loader outside Vue components
56
+ To control the loader state outside Vue components, use the following methods.
31
57
 
32
58
  <Source code={`
33
59
  import { loaderTopOn, loaderTopOff } from "vueless";
60
+
61
+ // show loader
62
+ loaderTopOn("/transactions");
63
+
64
+ // hide loader
65
+ loaderTopOff("/transactions");
34
66
  `} language="jsx" dark />
35
67
 
36
68
  ## Default config
@@ -4,54 +4,41 @@ export const LoaderTopSymbol = Symbol.for("vueless:loader-top");
4
4
 
5
5
  const isLoading = ref(true);
6
6
  const requestQueue = ref([]);
7
- const loaderRequestQueue = ref([]);
8
- const loaderRequestTimeout = ref(0);
9
- const componentLoaderRequestQueue = ref([]);
7
+ const requestTimeout = ref(0);
8
+ const componentRequestQueue = ref([]);
10
9
 
11
10
  function loaderTopOn(url) {
12
- loaderRequestQueue.value.push(url);
11
+ requestQueue.value.push(url);
13
12
  isLoading.value = true;
14
13
 
15
- clearTimeout(loaderRequestTimeout.value);
14
+ clearTimeout(requestTimeout.value);
16
15
  }
17
16
 
18
17
  function loaderTopOff(url) {
19
- loaderRequestQueue.value = url ? loaderRequestQueue.value.filter((item) => item !== url) : [];
18
+ requestQueue.value = url ? requestQueue.value.filter((item) => item !== url) : [];
20
19
 
21
- loaderRequestTimeout.value = setTimeout(() => {
22
- if (!loaderRequestQueue.value.length) {
20
+ requestTimeout.value = setTimeout(() => {
21
+ if (!requestQueue.value.length) {
23
22
  isLoading.value = false;
24
23
  }
25
24
  }, 50);
26
25
  }
27
26
 
28
- function addRequestUrl(url) {
29
- requestQueue.value.push(url);
30
- }
31
-
32
- function removeRequestUrl(url) {
33
- requestQueue.value = requestQueue.value.filter((item) => item !== url);
34
- }
35
-
36
27
  function setComponentRequestQueue(requests) {
37
- componentLoaderRequestQueue.value = [...componentLoaderRequestQueue.value, ...requests];
28
+ componentRequestQueue.value = [...componentRequestQueue.value, ...requests];
38
29
  }
39
30
 
40
31
  function removeComponentRequestQueue() {
41
- componentLoaderRequestQueue.value = [];
32
+ componentRequestQueue.value = [];
42
33
  }
43
34
 
44
35
  export function createLoaderTop() {
45
36
  return {
46
37
  isLoading: readonly(isLoading),
47
38
  requestQueue: readonly(requestQueue),
48
- loaderRequestQueue: readonly(loaderRequestQueue),
49
- loaderRequestTimeout: readonly(loaderRequestTimeout),
50
- componentLoaderRequestQueue: readonly(componentLoaderRequestQueue),
39
+ componentRequestQueue: readonly(componentRequestQueue),
51
40
  loaderTopOn,
52
41
  loaderTopOff,
53
- addRequestUrl,
54
- removeRequestUrl,
55
42
  setComponentRequestQueue,
56
43
  removeComponentRequestQueue,
57
44
  };
@@ -1,5 +1,8 @@
1
1
  import ULoaderTop from "../ui.loader-top";
2
2
  import UButton from "../ui.button";
3
+ import URow from "../ui.container-row";
4
+ import UGroup from "../ui.container-group";
5
+ import UBadge from "../ui.text-badge";
3
6
 
4
7
  import { useLoaderTop } from "./composables/useLoaderTop";
5
8
  import { loaderTopOff, loaderTopOn } from "./services/loaderTop.service";
@@ -11,7 +14,7 @@ import { getArgTypes } from "../service.storybook";
11
14
  */
12
15
  export default {
13
16
  id: "9020",
14
- title: "Loaders and Skeletons / Loader top",
17
+ title: "Loaders and Skeletons / Loader Top",
15
18
  component: ULoaderTop,
16
19
  argTypes: {
17
20
  ...getArgTypes(ULoaderTop.name),
@@ -19,26 +22,24 @@ export default {
19
22
  };
20
23
 
21
24
  const DefaultTemplate = (args) => ({
22
- components: { ULoaderTop, UButton },
25
+ components: { ULoaderTop, UButton, URow },
23
26
  setup() {
24
27
  const { loaderTopOn, loaderTopOff } = useLoaderTop();
25
28
 
26
29
  return { args, loaderTopOn, loaderTopOff };
27
30
  },
28
31
  template: `
29
- <div>
30
- <ULoaderTop color="blue" v-bind="args" resource-names="https://api.publicapis.org/entries"/>
32
+ <ULoaderTop color="blue" v-bind="args" resources="https://api.publicapis.org/entries"/>
31
33
 
32
- <div class="flex gap-2">
33
- <UButton label="On" @click="setLoaderOn('https://api.publicapis.org/entries')" />
34
- <UButton label="Off" @click="setLoaderOff('https://api.publicapis.org/entries')" />
35
- </div>
36
- </div>
34
+ <URow gap="sm">
35
+ <UButton label="On" size="sm" @click="loaderTopOn('https://api.publicapis.org/entries')" />
36
+ <UButton label="Off" size="sm" @click="loaderTopOff('https://api.publicapis.org/entries')" />
37
+ </URow>
37
38
  `,
38
39
  });
39
40
 
40
41
  const ColorsTemplate = (args, { argTypes } = {}) => ({
41
- components: { ULoaderTop, UButton },
42
+ components: { ULoaderTop, UButton, UGroup, URow, UBadge },
42
43
  setup() {
43
44
  return {
44
45
  args,
@@ -48,19 +49,23 @@ const ColorsTemplate = (args, { argTypes } = {}) => ({
48
49
  };
49
50
  },
50
51
  template: `
51
- <div class="flex gap-4 flex-col">
52
- <ULoaderTop
53
- class="static"
54
- v-for="(color, index) in colors"
55
- :color="color"
56
- v-bind="args"
57
- :key="index"
58
- />
59
- </div>
60
- <div class="flex gap-2 pt-4">
61
- <UButton label="On" @click="loaderTopOn('https://api.publicapis.org/entries')" />
62
- <UButton label="Off" @click="loaderTopOff('https://api.publicapis.org/entries')" />
63
- </div>
52
+ <UGroup>
53
+ <URow gap="sm" class="pb-4">
54
+ <UButton label="On" size="sm" @click="loaderTopOn('https://api.publicapis.org/images')" />
55
+ <UButton label="Off" size="sm" @click="loaderTopOff('https://api.publicapis.org/images')" />
56
+ </URow>
57
+
58
+ <URow align="center" v-for="(color, index) in colors" :key="index">
59
+ <UBadge :label="color" :color="color" />
60
+ <ULoaderTop
61
+ resources="https://api.publicapis.org/images"
62
+ class="static"
63
+ :color="color"
64
+ v-bind="args"
65
+ />
66
+ </URow>
67
+
68
+ </UGroup>
64
69
  `,
65
70
  });
66
71
 
@@ -19,14 +19,6 @@ import { useAttrs } from "./composables/attrs.composable";
19
19
  defineOptions({ name: "ULoaderTop", inheritAttrs: false });
20
20
 
21
21
  const props = defineProps({
22
- /**
23
- * The name of API resource (endpoint URI).
24
- */
25
- resourceNames: {
26
- type: [String, Array],
27
- default: "",
28
- },
29
-
30
22
  /**
31
23
  * The color of the loader stripe.
32
24
  * @values brand, grayscale, gray, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose, white
@@ -35,6 +27,14 @@ const props = defineProps({
35
27
  type: String,
36
28
  default: UIService.get(defaultConfig, ULoaderTop).default.color,
37
29
  },
30
+
31
+ /**
32
+ * API resource names (endpoint URIs).
33
+ */
34
+ resources: {
35
+ type: [String, Array],
36
+ default: "",
37
+ },
38
38
  });
39
39
 
40
40
  const error = ref(false);
@@ -44,13 +44,13 @@ const opacity = ref(1);
44
44
  const status = ref(null);
45
45
 
46
46
  const {
47
- loaderRequestQueue,
48
47
  isLoading,
49
- componentLoaderRequestQueue,
48
+ requestQueue,
49
+ loaderTopOn,
50
+ loaderTopOff,
51
+ loaderRequestQueue,
50
52
  setComponentRequestQueue,
51
53
  removeComponentRequestQueue,
52
- loaderTopOff,
53
- loaderTopOn,
54
54
  } = useLoaderTop();
55
55
  const { progressAttrs } = useAttrs(props, { error, isMobileApp });
56
56
 
@@ -66,13 +66,13 @@ const barStyle = computed(() => {
66
66
  });
67
67
 
68
68
  const resourceNamesArray = computed(() => {
69
- return Array.isArray(props.resourceNames) ? [...props.resourceNames] : [props.resourceNames];
69
+ return Array.isArray(props.resources) ? [...props.resources] : [props.resources];
70
70
  });
71
71
 
72
- watch(loaderRequestQueue, onChangeRequestsQueue, { deep: true });
72
+ watch(requestQueue, onChangeRequestsQueue, { deep: true });
73
73
  watch(isLoading, onChangeLoadingState, { deep: true });
74
74
 
75
- if (props.resourceNames) {
75
+ if (props.resources) {
76
76
  setComponentRequestQueue(resourceNamesArray.value);
77
77
  }
78
78
 
@@ -82,7 +82,7 @@ onMounted(() => {
82
82
  });
83
83
 
84
84
  onBeforeUnmount(() => {
85
- if (props.resourceNames) {
85
+ if (props.resources) {
86
86
  removeComponentRequestQueue();
87
87
  }
88
88
  });
@@ -107,7 +107,7 @@ function requestWithoutQuery(request) {
107
107
  }
108
108
 
109
109
  function onChangeLoadingState() {
110
- if (!props.resourceNames && isStarted.value && show.value && !isLoading.value) {
110
+ if (!props.resources && isStarted.value && show.value && !isLoading.value) {
111
111
  done();
112
112
  }
113
113
  }
@@ -115,10 +115,10 @@ function onChangeLoadingState() {
115
115
  function onChangeRequestsQueue() {
116
116
  let isActiveRequests = false;
117
117
 
118
- if (props.resourceNames) {
118
+ if (props.resources) {
119
119
  resourceNamesArray.value.forEach((item) => {
120
120
  if (!isActiveRequests) {
121
- const activeRequest = loaderRequestQueue.value.find(
121
+ const activeRequest = requestQueue.value.find(
122
122
  (request) => requestWithoutQuery(request) === item,
123
123
  );
124
124
 
@@ -132,8 +132,8 @@ function onChangeRequestsQueue() {
132
132
  done();
133
133
  }
134
134
  } else {
135
- loaderRequestQueue.value.forEach((item) => {
136
- const activeRequest = componentLoaderRequestQueue.value.find(
135
+ requestQueue.value.forEach((item) => {
136
+ const activeRequest = loaderRequestQueue.value.find(
137
137
  (request) => request === requestWithoutQuery(item),
138
138
  );
139
139
 
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "framework": "vue",
3
3
  "name": "vueless",
4
- "version": "0.0.176",
4
+ "version": "0.0.178",
5
5
  "contributions": {
6
6
  "html": {
7
7
  "description-markup": "markdown",
@@ -806,6 +806,24 @@
806
806
  "type": "string"
807
807
  },
808
808
  "default": "\"\""
809
+ },
810
+ {
811
+ "name": "iconLeft",
812
+ "description": "Left side icon name.",
813
+ "value": {
814
+ "kind": "expression",
815
+ "type": "string"
816
+ },
817
+ "default": "\"\""
818
+ },
819
+ {
820
+ "name": "iconRight",
821
+ "description": "Right side icon name.",
822
+ "value": {
823
+ "kind": "expression",
824
+ "type": "string"
825
+ },
826
+ "default": "\"\""
809
827
  }
810
828
  ],
811
829
  "events": [
@@ -816,7 +834,7 @@
816
834
  "slots": [
817
835
  {
818
836
  "name": "left",
819
- "description": "Use it to add something before text."
837
+ "description": "Use it to add icon before text."
820
838
  },
821
839
  {
822
840
  "name": "default",
@@ -824,7 +842,7 @@
824
842
  },
825
843
  {
826
844
  "name": "right",
827
- "description": "Use it to add something after text."
845
+ "description": "Use it to add icon after text."
828
846
  }
829
847
  ],
830
848
  "source": {
@@ -1144,7 +1162,7 @@
1144
1162
  "description": "Checkbox size.",
1145
1163
  "value": {
1146
1164
  "kind": "expression",
1147
- "type": "'sm' | 'md' | 'lg'"
1165
+ "type": "'xs' | 'sm' | 'md' | 'lg' | 'xl'"
1148
1166
  },
1149
1167
  "default": "md"
1150
1168
  },
@@ -4363,7 +4381,7 @@
4363
4381
  "description": "Set label size.",
4364
4382
  "value": {
4365
4383
  "kind": "expression",
4366
- "type": "'sm' | 'md' | 'lg'"
4384
+ "type": "'xs' | 'sm' | 'md' | 'lg' | 'xl'"
4367
4385
  },
4368
4386
  "default": "md"
4369
4387
  },
@@ -4742,22 +4760,22 @@
4742
4760
  "description": "",
4743
4761
  "attributes": [
4744
4762
  {
4745
- "name": "resourceNames",
4746
- "description": "The name of API resource (endpoint URI).",
4763
+ "name": "color",
4764
+ "description": "The color of the loader stripe.",
4747
4765
  "value": {
4748
4766
  "kind": "expression",
4749
- "type": "string|array"
4767
+ "type": "'brand' | 'grayscale' | 'gray' | 'red' | 'orange' | 'amber' | 'yellow' | 'lime' | 'green' | 'emerald' | 'teal' | 'cyan' | 'sky' | 'blue' | 'indigo' | 'violet' | 'purple' | 'fuchsia' | 'pink' | 'rose' | 'white'"
4750
4768
  },
4751
- "default": "\"\""
4769
+ "default": "brand"
4752
4770
  },
4753
4771
  {
4754
- "name": "color",
4755
- "description": "The color of the loader stripe.",
4772
+ "name": "resources",
4773
+ "description": "API resource names (endpoint URIs).",
4756
4774
  "value": {
4757
4775
  "kind": "expression",
4758
- "type": "'brand' | 'grayscale' | 'gray' | 'red' | 'orange' | 'amber' | 'yellow' | 'lime' | 'green' | 'emerald' | 'teal' | 'cyan' | 'sky' | 'blue' | 'indigo' | 'violet' | 'purple' | 'fuchsia' | 'pink' | 'rose' | 'white'"
4776
+ "type": "string|array"
4759
4777
  },
4760
- "default": "brand"
4778
+ "default": "\"\""
4761
4779
  }
4762
4780
  ],
4763
4781
  "source": {
@@ -5753,7 +5771,7 @@
5753
5771
  "description": "Radio size.",
5754
5772
  "value": {
5755
5773
  "kind": "expression",
5756
- "type": "'sm' | 'md' | 'lg'"
5774
+ "type": "'xs' | 'sm' | 'md' | 'lg' | 'xl'"
5757
5775
  },
5758
5776
  "default": "md"
5759
5777
  },
@@ -5839,117 +5857,6 @@
5839
5857
  "symbol": "default"
5840
5858
  }
5841
5859
  },
5842
- {
5843
- "name": "URadioCard",
5844
- "description": "",
5845
- "attributes": [
5846
- {
5847
- "name": "name",
5848
- "required": true,
5849
- "description": "Set radio card name.",
5850
- "value": {
5851
- "kind": "expression",
5852
- "type": "string"
5853
- },
5854
- "default": "\"\""
5855
- },
5856
- {
5857
- "name": "options",
5858
- "description": "Set options for component.",
5859
- "value": {
5860
- "kind": "expression",
5861
- "type": "array"
5862
- },
5863
- "default": "[]"
5864
- },
5865
- {
5866
- "name": "modelValue",
5867
- "description": "Set component value.",
5868
- "value": {
5869
- "kind": "expression",
5870
- "type": "string|number|boolean"
5871
- },
5872
- "default": "\"\""
5873
- },
5874
- {
5875
- "name": "gridCols",
5876
- "description": "Set grid cols number.",
5877
- "value": {
5878
- "kind": "expression",
5879
- "type": "number"
5880
- },
5881
- "default": "2"
5882
- },
5883
- {
5884
- "name": "withIcon",
5885
- "description": "Show / hide component icon.",
5886
- "value": {
5887
- "kind": "expression",
5888
- "type": "boolean"
5889
- },
5890
- "default": "true"
5891
- },
5892
- {
5893
- "name": "color",
5894
- "description": "The color of the icon.",
5895
- "value": {
5896
- "kind": "expression",
5897
- "type": "'brand' | 'grayscale' | 'black' | 'white' | 'red' | 'orange' | 'amber' | 'yellow' | 'lime' | 'green' | 'emerald' | 'teal' | 'cyan' | 'sky' | 'blue' | 'indigo' | 'violet' | 'purple' | 'fuchsia' | 'pink' | 'rose'"
5898
- },
5899
- "default": "brand"
5900
- },
5901
- {
5902
- "name": "id",
5903
- "description": "@ignore: Generates unique element id.",
5904
- "value": {
5905
- "kind": "expression",
5906
- "type": "string"
5907
- },
5908
- "default": "() => getRandomId()"
5909
- },
5910
- {
5911
- "name": "labelAlign",
5912
- "value": {
5913
- "kind": "expression",
5914
- "type": "string"
5915
- },
5916
- "default": "top"
5917
- },
5918
- {
5919
- "name": "config",
5920
- "description": "Sets component ui config object.",
5921
- "value": {
5922
- "kind": "expression",
5923
- "type": "object"
5924
- },
5925
- "default": "{}"
5926
- },
5927
- {
5928
- "name": "dataCy",
5929
- "description": "Sets data-cy attribute for automated testing.",
5930
- "value": {
5931
- "kind": "expression",
5932
- "type": "string"
5933
- },
5934
- "default": "\"\""
5935
- }
5936
- ],
5937
- "events": [
5938
- {
5939
- "name": "update:modelValue"
5940
- }
5941
- ],
5942
- "slots": [
5943
- {
5944
- "name": "icon",
5945
- "description": "Use it to add icon."
5946
- }
5947
- ],
5948
- "source": {
5949
- "module": "./src/ui.form-radio-card/index.vue",
5950
- "symbol": "default"
5951
- }
5952
- },
5953
5860
  {
5954
5861
  "name": "URadioGroup",
5955
5862
  "description": "",
@@ -1,16 +0,0 @@
1
- import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Source } from "@storybook/blocks";
2
- import { getSource } from "../service.storybook";
3
-
4
- import * as stories from "./index.stories";
5
- import defaultConfig from "./configs/default.config?raw"
6
-
7
- <Meta of={stories} />
8
- <Title of={stories} />
9
- <Subtitle of={stories} />
10
- <Description of={stories} />
11
- <Primary of={stories} />
12
- <Controls of={stories.Default} />
13
- <Stories of={stories} />
14
-
15
- ## Default config
16
- <Source code={getSource(defaultConfig)} language="jsx" dark />
@@ -1,37 +0,0 @@
1
- import useUI from "../../composable.ui";
2
- import { cva, cx } from "../../service.ui";
3
-
4
- import defaultConfig from "../configs/default.config";
5
- import { computed } from "vue";
6
-
7
- export function useAttrs(props) {
8
- const { config, getAttrs } = useUI(defaultConfig, () => props.config);
9
- const { radio } = config.value;
10
-
11
- const cvaRadio = cva({
12
- base: radio.base,
13
- variants: radio.variants,
14
- compoundVariants: radio.compoundVariants,
15
- });
16
-
17
- const radioClasses = computed(() => cvaRadio({ color: props.color }));
18
-
19
- const wrapperAttrsRaw = getAttrs("wrapper");
20
- const itemsAttrs = getAttrs("items");
21
- const labelAttrs = getAttrs("label");
22
- const radioAttrs = getAttrs("radio", { isComponent: true, classes: radioClasses });
23
- const iconAttrs = getAttrs("icon", { isComponent: true });
24
-
25
- const wrapperAttrs = computed(() => (classes) => ({
26
- ...wrapperAttrsRaw.value,
27
- class: cx([wrapperAttrsRaw.value.class, classes]),
28
- }));
29
-
30
- return {
31
- radioAttrs,
32
- iconAttrs,
33
- wrapperAttrs,
34
- labelAttrs,
35
- itemsAttrs,
36
- };
37
- }
@@ -1,31 +0,0 @@
1
- export default /*tw*/ {
2
- wrapper: "grid grid-rows-1 gap-4 md:gap-6 text-center",
3
- title: "text-base font-normal text-gray-900 mb-1 mt-3",
4
- description: "text-xs font-normal text-gray-500/[85]",
5
- radio: {
6
- base: "w-full right-4 top-2 !gap-0",
7
- radio: "absolute right-6 top-4",
8
- },
9
- label: "size-full cursor-pointer",
10
- items: `
11
- relative mr-1 w-full cursor-pointer rounded-lg border border-solid border-gray-300 px-6 py-4
12
- focus-within:border-gray-500 focus-within:ring-4 focus-within:ring-gray-600/[.15] hover:border-gray-400
13
- `,
14
- icon: "mb-3 flex justify-center",
15
- defaultVariants: {
16
- color: "brand",
17
- labelAlign: "top",
18
- gridCols: 2,
19
- withIcon: true,
20
- },
21
- safelist: (colors) => [
22
- { pattern: `border-(${colors})-100`, variants: ["disabled"] },
23
- { pattern: `border-(${colors})-300` },
24
- { pattern: `border-(${colors})-400`, variants: ["hover"] },
25
- { pattern: `border-(${colors})-500`, variants: ["focus", "active"] },
26
- { pattern: `text-(${colors})-500` },
27
- { pattern: `bg-(${colors})-100`, variants: ["disabled"] },
28
- { pattern: `bg-(${colors})-500`, variants: ["focus"] },
29
- { pattern: `ring-(${colors})-200`, variants: ["focus"] },
30
- ],
31
- };
@@ -1,5 +0,0 @@
1
- /*
2
- This const is needed to prevent the issue in script setup:
3
- `defineProps` is referencing locally declared variables. (vue/valid-define-props)
4
- */
5
- export const URadioCard = "URadioCard";