@naptics/vue-collection 0.0.3 → 0.0.4

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 (47) hide show
  1. package/README.md +5 -1
  2. package/components/NAlert.js +81 -0
  3. package/components/NBadge.js +57 -0
  4. package/components/NBreadcrub.js +66 -0
  5. package/components/NButton.js +65 -0
  6. package/components/NCheckbox.js +42 -0
  7. package/components/NCheckboxLabel.js +39 -0
  8. package/components/NCrudModal.js +105 -0
  9. package/components/NDialog.js +160 -0
  10. package/components/NDropdown.js +108 -0
  11. package/components/NDropzone.js +210 -0
  12. package/components/NForm.js +28 -0
  13. package/components/NFormModal.js +54 -0
  14. package/components/NIconButton.js +81 -0
  15. package/components/NIconCircle.js +66 -0
  16. package/components/NInput.js +105 -0
  17. package/components/NInputPhone.js +46 -0
  18. package/components/NInputSelect.js +114 -0
  19. package/components/NInputSuggestion.js +63 -0
  20. package/components/NLink.js +59 -0
  21. package/components/NList.js +24 -0
  22. package/components/NLoadingIndicator.js +53 -0
  23. package/components/NModal.js +210 -0
  24. package/components/NPagination.js +108 -0
  25. package/components/NSearchbar.js +66 -0
  26. package/components/NSearchbarList.js +36 -0
  27. package/components/NSelect.js +84 -0
  28. package/components/NSuggestionList.js +156 -0
  29. package/components/NTable.js +126 -0
  30. package/components/NTableAction.js +49 -0
  31. package/components/NTextArea.js +128 -0
  32. package/components/NTooltip.js +178 -0
  33. package/components/NValInput.js +104 -0
  34. package/components/ValidatedForm.js +18 -18
  35. package/i18n/index.js +4 -8
  36. package/index.js +1 -1
  37. package/package.json +9 -2
  38. package/utils/breakpoints.js +21 -21
  39. package/utils/component.js +17 -9
  40. package/utils/deferred.js +12 -12
  41. package/utils/identifiable.js +27 -29
  42. package/utils/stringMaxLength.js +8 -13
  43. package/utils/tailwind.js +1 -1
  44. package/utils/utils.js +5 -5
  45. package/utils/vModel.js +82 -73
  46. package/utils/validation.js +55 -81
  47. package/utils/vue.js +7 -5
@@ -0,0 +1,178 @@
1
+ import { withDirectives as _withDirectives, vShow as _vShow, Fragment as _Fragment, createVNode as _createVNode } from "vue";
2
+ import { createComponent, createProps } from '../utils/component';
3
+ import { uniqueId } from '../utils/utils';
4
+ import { computed, onMounted, ref, watch, onUnmounted, Transition } from 'vue';
5
+ import { createPopper } from '@popperjs/core';
6
+ import { watchRef } from '../utils/vue';
7
+ import './NTooltip.css';
8
+ export const nTooltipProps = createProps({
9
+ /**
10
+ * The text content of the tooltip.
11
+ */
12
+ text: String,
13
+ /**
14
+ * A slot to replace the content of the tooltip. This will override the `text` prop.
15
+ */
16
+ content: Function,
17
+ /**
18
+ * If set to `true` the tooltip is shown constantly.
19
+ */
20
+ show: Boolean,
21
+ /**
22
+ * If set to `true` the tooltip is hidden constantly.
23
+ */
24
+ hide: Boolean,
25
+ /**
26
+ * If set to `true` the `block` class is applied to the tooltip.
27
+ * This should be set if the content in the default slot is also block.
28
+ */
29
+ block: Boolean,
30
+ /**
31
+ * The placement of the tooltip.
32
+ */
33
+ placement: {
34
+ type: String,
35
+ default: 'auto'
36
+ },
37
+ /**
38
+ * The maximum width of the tooltip.
39
+ */
40
+ maxWidth: {
41
+ type: String,
42
+ default: 'max-w-xs'
43
+ }
44
+ });
45
+ /**
46
+ * These props are made to use on a component which implements the tooltip
47
+ * and wants it to be controllable via the own props.
48
+ * e.g. `text` is now called `tooltipText`.
49
+ * They can be mapped to the normal tooltip props with {@link mapTooltipProps}
50
+ */
51
+ export const nToolTipPropsForImplementor = {
52
+ /**
53
+ * Adds a tooltip to the component with the specified text.
54
+ * @see {@link nTooltipProps.text}
55
+ */
56
+ tooltipText: nTooltipProps.text,
57
+ /**
58
+ * A slot for the tooltip of this component.
59
+ * If the slot is set, the tooltip with the specified content is added to the component.
60
+ * @see {@link nTooltipProps.content}
61
+ */
62
+ tooltipContent: nTooltipProps.content,
63
+ /**
64
+ * @see {@link nTooltipProps.hide}
65
+ */
66
+ tooltipHide: nTooltipProps.hide,
67
+ /**
68
+ * @see {@link nTooltipProps.show}
69
+ */
70
+ tooltipShow: nTooltipProps.show,
71
+ /**
72
+ * @see {@link nTooltipProps.placement}
73
+ */
74
+ tooltipPlacement: nTooltipProps.placement,
75
+ /**
76
+ * @see {@link nTooltipProps.maxWidth}
77
+ */
78
+ tooltipMaxWidth: nTooltipProps.maxWidth
79
+ };
80
+ /**
81
+ * Maps the {@link nToolTipPropsForImplementor} props to normal tooltip props
82
+ * @returns an object containing the normal tooltip props.
83
+ */
84
+ export function mapTooltipProps(props) {
85
+ return {
86
+ text: props.tooltipText,
87
+ content: props.tooltipContent,
88
+ hide: props.tooltipHide,
89
+ show: props.tooltipShow,
90
+ placement: props.tooltipPlacement,
91
+ maxWidth: props.tooltipMaxWidth
92
+ };
93
+ }
94
+ /**
95
+ * The `NTooltip` is a wrapper for any component which adds a tooltip to it.
96
+ * Any component can just be passed in the default slot and a tooltip will be added to it.
97
+ * Note that this component disappears when neither the `text` nor the `content`
98
+ * prop is passed as the tooltip would then be empty.
99
+ * If this is the case, the default slot will just be rendered inside a div.
100
+ * @example
101
+ * <NTooltip text="Hello">
102
+ * <NButton />
103
+ * </NTooltip>
104
+ */
105
+ export default createComponent('NTooltip', nTooltipProps, (props, {
106
+ slots
107
+ }) => {
108
+ return () => _createVNode("div", {
109
+ "class": props.block ? 'block' : 'inline-block'
110
+ }, [props.content || props.text ? _createVNode(NTooltipBase, props, {
111
+ default: () => [slots.default?.()]
112
+ }) : slots.default?.()]);
113
+ });
114
+ const NTooltipBase = createComponent('NTooltipBase', nTooltipProps, (props, {
115
+ slots
116
+ }) => {
117
+ let popperInstance = null;
118
+ const contentId = `content-${uniqueId()}`;
119
+ const tooltipId = `tooltip-${uniqueId()}`;
120
+ function createTooltip() {
121
+ const content = document.getElementById(contentId);
122
+ const tooltip = document.getElementById(tooltipId);
123
+ if (content && tooltip) {
124
+ popperInstance = createPopper(content, tooltip, {
125
+ placement: props.placement,
126
+ modifiers: [{
127
+ name: 'offset',
128
+ options: {
129
+ offset: [0, 8]
130
+ }
131
+ }]
132
+ });
133
+ } else {
134
+ console.error('Could not create tooltip. HTML elements for content or tooltip were not found.');
135
+ }
136
+ }
137
+ function destroyTooltip() {
138
+ popperInstance?.destroy();
139
+ popperInstance = null;
140
+ }
141
+ onMounted(createTooltip);
142
+ onUnmounted(destroyTooltip);
143
+ watch(() => props.placement, newPlacement => popperInstance?.setOptions({
144
+ placement: newPlacement
145
+ }));
146
+ const isHoveringContent = ref(false);
147
+ const isHoveringTooltip = ref(false);
148
+ const isHovering = computed(() => isHoveringContent.value || isHoveringTooltip.value);
149
+ const showTooltip = computed(() => props.show || !props.hide && isHovering.value);
150
+ watchRef(showTooltip, () => popperInstance?.update());
151
+ return () => _createVNode(_Fragment, null, [_createVNode("div", {
152
+ "class": "p-[10px] -m-[10px]",
153
+ "onMouseleave": () => setTimeout(() => isHoveringContent.value = false, 10)
154
+ }, [_createVNode("div", {
155
+ "id": contentId,
156
+ "onMouseenter": () => isHoveringContent.value = true
157
+ }, [slots.default?.()])]), _createVNode(Transition, {
158
+ "enterActiveClass": "transition-opacity ease-out duration-100",
159
+ "enterFromClass": "opacity-0",
160
+ "enterToClass": "opacity-100",
161
+ "leaveActiveClass": "transition-opacity ease-in duration-75",
162
+ "leaveFromClass": "opacity-100",
163
+ "leaveToClass": "opacity-0"
164
+ }, {
165
+ default: () => [_withDirectives(_createVNode("div", {
166
+ "id": tooltipId,
167
+ "role": "tooltip",
168
+ "onMouseenter": () => isHoveringTooltip.value = true,
169
+ "onMouseleave": () => isHoveringTooltip.value = false,
170
+ "class": [isHovering.value ? 'z-20' : 'z-10', props.maxWidth, 'tooltip']
171
+ }, [_createVNode("div", {
172
+ "class": "bg-white rounded-md py-2 px-4 shadow-lg border-default-200 border text-sm font-normal text-default-700"
173
+ }, [props.content?.() || props.text]), _createVNode("div", {
174
+ "data-popper-arrow": true,
175
+ "class": "arrow"
176
+ }, null)]), [[_vShow, showTooltip.value]])]
177
+ })]);
178
+ });
@@ -0,0 +1,104 @@
1
+ import { createVNode as _createVNode, mergeProps as _mergeProps } from "vue";
2
+ import { createComponent, createProps } from '../utils/component';
3
+ import { computed } from 'vue';
4
+ import { ref, reactive, watch } from 'vue';
5
+ import NInput, { nInputProps } from './NInput';
6
+ import { validate, required } from '../utils/validation';
7
+ export const validationProps = createProps({
8
+ /**
9
+ * If set to `true` this input is always valid when its value is empty.
10
+ * If set to `false` the input receives the {@link required} rule. Default is `false`.
11
+ */
12
+ optional: Boolean,
13
+ /**
14
+ * The rules which this input is checked with.
15
+ * The rules are checked sequentially and the error of the first failed rule is displayed.
16
+ * If `optional` is set to false, the rule {@link required} will be checked first.
17
+ */
18
+ rules: {
19
+ type: [Function, Array],
20
+ default: () => []
21
+ },
22
+ /**
23
+ * The form, which this input will be added to.
24
+ * On initialization, this input will call {@link ValidatedForm.addInput} passing itself to the form.
25
+ */
26
+ form: Object,
27
+ /**
28
+ * Overrides the internal error state. If set to true, it will always display an error.
29
+ */
30
+ error: Boolean,
31
+ /**
32
+ * Overrides the internal error message. If set, this message is always displayed.
33
+ */
34
+ errorMessage: String,
35
+ /**
36
+ * If set to `true` the error message is not shown.
37
+ * However, the input is still marked red if it is in an error state.
38
+ */
39
+ hideErrorMessage: Boolean,
40
+ /**
41
+ * Disables the validation on blur. Should only be used in special occasions.
42
+ */
43
+ disableBlurValidation: Boolean
44
+ });
45
+ export const nValInputProps = createProps({
46
+ ...nInputProps,
47
+ ...validationProps,
48
+ /**
49
+ * A slot to replace the input.
50
+ */
51
+ input: Function
52
+ });
53
+ /**
54
+ * The `NValInput` is a `NInput` with custom validation.
55
+ */
56
+ export default createComponent('NValInput', nValInputProps, (props, context) => {
57
+ const rules = computed(() => {
58
+ const otherRules = Array.isArray(props.rules) ? props.rules : [props.rules];
59
+ return props.optional ? otherRules : [required, ...otherRules];
60
+ });
61
+ const validationResult = ref();
62
+ const validateRules = input => {
63
+ const result = validate(input, rules.value);
64
+ validationResult.value = result;
65
+ return result;
66
+ };
67
+ const showError = computed(() => props.error || validationResult.value != null && !validationResult.value.isValid);
68
+ const showErrorMessage = computed(() => !props.hideErrorMessage && showError.value);
69
+ const errorMessage = computed(() => props.errorMessage || validationResult.value?.errorMessage);
70
+ const validateIfError = (value = props.value) => {
71
+ if (showError.value) validateRules(value);
72
+ };
73
+ watch(() => props.value, () => validateIfError());
74
+ watch(() => rules.value, () => validateIfError());
75
+ const onBlur = () => {
76
+ if (!props.disableBlurValidation) validateRules(props.value);
77
+ props.onBlur?.();
78
+ };
79
+ const onUpdateValue = newValue => {
80
+ validateIfError(newValue);
81
+ props.onUpdateValue?.(newValue);
82
+ };
83
+ const inputSlotProps = reactive({
84
+ onBlur,
85
+ onUpdateValue,
86
+ error: showError
87
+ });
88
+ const inputRef = ref();
89
+ const expose = {
90
+ validate: () => validateRules(props.value),
91
+ reset: () => validationResult.value = undefined,
92
+ focus: () => inputRef.value?.focus()
93
+ };
94
+ context.expose(expose);
95
+ props.form?.addInput(expose);
96
+ return () => _createVNode("div", null, [props.input?.(inputSlotProps) || _createVNode(NInput, _mergeProps({
97
+ "ref": inputRef
98
+ }, {
99
+ ...props,
100
+ ...inputSlotProps
101
+ }), null), showErrorMessage.value && _createVNode("p", {
102
+ "class": "text-red-500 text-xs mt-1"
103
+ }, [errorMessage.value])]);
104
+ });
@@ -3,23 +3,23 @@
3
3
  * @returns the instance of the new form.
4
4
  */
5
5
  export function createValidatedForm() {
6
- return new ValidatedFormImpl();
6
+ return new ValidatedFormImpl();
7
7
  }
8
8
  class ValidatedFormImpl {
9
- inputs = [];
10
- addInput(input) {
11
- this.inputs.push(input);
12
- }
13
- validate() {
14
- const results = this.inputs.map(input => input.validate());
15
- // return first invalid result
16
- for (const result of results)
17
- if (result && !result.isValid)
18
- return result;
19
- // else return valid result
20
- return { isValid: true };
21
- }
22
- reset() {
23
- this.inputs.forEach(input => input.reset());
24
- }
25
- }
9
+ inputs = [];
10
+ addInput(input) {
11
+ this.inputs.push(input);
12
+ }
13
+ validate() {
14
+ const results = this.inputs.map(input => input.validate());
15
+ // return first invalid result
16
+ for (const result of results) if (result && !result.isValid) return result;
17
+ // else return valid result
18
+ return {
19
+ isValid: true
20
+ };
21
+ }
22
+ reset() {
23
+ this.inputs.forEach(input => input.reset());
24
+ }
25
+ }
package/i18n/index.js CHANGED
@@ -6,7 +6,7 @@ let provider = undefined;
6
6
  * @param newProvider
7
7
  */
8
8
  export function registerTranslationProvider(newProvider) {
9
- provider = newProvider;
9
+ provider = newProvider;
10
10
  }
11
11
  /**
12
12
  * Translates the specified key with the according message.
@@ -15,9 +15,7 @@ export function registerTranslationProvider(newProvider) {
15
15
  * @returns the translated message.
16
16
  */
17
17
  export function trsl(key, params) {
18
- if (!provider)
19
- console.warn('Vue Collection: No translation provider has been registered!');
20
- return provider?.trsl(key, params) ?? key;
18
+ return provider?.trsl(key, params) ?? key;
21
19
  }
22
20
  /**
23
21
  * Translates the specified key using pluralization.
@@ -29,7 +27,5 @@ export function trsl(key, params) {
29
27
  * @see trsl
30
28
  */
31
29
  export function trslc(key, count, params) {
32
- if (!provider)
33
- console.warn('Vue Collection: No translation provider has been registered!');
34
- return provider?.trslc(key, count, params) ?? key;
35
- }
30
+ return provider?.trslc(key, count, params) ?? key;
31
+ }
package/index.js CHANGED
@@ -64,4 +64,4 @@ export { NValInput };
64
64
  import { createValidatedForm } from './components/ValidatedForm';
65
65
  export { createValidatedForm };
66
66
  import { createComponent, createView, createProps } from './utils/component';
67
- export { createComponent, createView, createProps };
67
+ export { createComponent, createView, createProps };
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@naptics/vue-collection",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "main": "./index.js",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/naptics/vue-collection"
8
+ },
5
9
  "scripts": {
6
10
  "dev": "vite",
7
11
  "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
@@ -12,7 +16,7 @@
12
16
  "build-demo": "run-p type-check-demo build-only-demo",
13
17
  "build-lib": "run-p type-check-lib build-only-lib",
14
18
  "build-only-demo": "vite build",
15
- "build-only-lib": "rm -rf ./lib && tsc --project tsconfig.lib.json && mv ./lib/src/lib/* ./lib && rm -rf ./lib/src && rm ./lib/tsconfig.lib.tsbuildinfo && cp ./src/lib/components/*.css ./lib/components"
19
+ "build-only-lib": "bash ./scripts/build-lib.sh"
16
20
  },
17
21
  "dependencies": {
18
22
  "@headlessui/vue": "^1.7.10",
@@ -24,6 +28,8 @@
24
28
  "vue": "^3.2.36"
25
29
  },
26
30
  "devDependencies": {
31
+ "@babel/cli": "^7.21.0",
32
+ "@babel/core": "^7.21.3",
27
33
  "@intlify/unplugin-vue-i18n": "^0.8.2",
28
34
  "@rushstack/eslint-patch": "^1.2.0",
29
35
  "@tailwindcss/forms": "^0.5.3",
@@ -31,6 +37,7 @@
31
37
  "@types/node": "^18.14.0",
32
38
  "@vitejs/plugin-vue": "^4.0.0",
33
39
  "@vitejs/plugin-vue-jsx": "^3.0.0",
40
+ "@vue/babel-plugin-jsx": "^1.1.1",
34
41
  "@vue/eslint-config-prettier": "^7.1.0",
35
42
  "@vue/eslint-config-typescript": "^11.0.2",
36
43
  "@vue/test-utils": "^2.3.0",
@@ -1,10 +1,10 @@
1
1
  import { computed, ref } from 'vue';
2
2
  export const breakpoints = {
3
- sm: 640,
4
- md: 768,
5
- lg: 1024,
6
- xl: 1280,
7
- '2xl': 1536,
3
+ sm: 640,
4
+ md: 768,
5
+ lg: 1024,
6
+ xl: 1280,
7
+ '2xl': 1536
8
8
  };
9
9
  export const bodyWidth = ref(document.body.clientWidth);
10
10
  /**
@@ -12,26 +12,26 @@ export const bodyWidth = ref(document.body.clientWidth);
12
12
  * It sets a `window.onresize` listener.
13
13
  */
14
14
  export function addDocumentResizeEventListener() {
15
- window.onresize = () => {
16
- bodyWidth.value = document.body.clientWidth;
17
- };
15
+ window.onresize = () => {
16
+ bodyWidth.value = document.body.clientWidth;
17
+ };
18
18
  }
19
19
  export function isWidthBreakpoint(breakpoint) {
20
- switch (breakpoint) {
21
- case 'sm':
22
- return isWidthSm;
23
- case 'md':
24
- return isWidthMd;
25
- case 'lg':
26
- return isWidthLg;
27
- case 'xl':
28
- return isWidthXl;
29
- case '2xl':
30
- return isWidth2xl;
31
- }
20
+ switch (breakpoint) {
21
+ case 'sm':
22
+ return isWidthSm;
23
+ case 'md':
24
+ return isWidthMd;
25
+ case 'lg':
26
+ return isWidthLg;
27
+ case 'xl':
28
+ return isWidthXl;
29
+ case '2xl':
30
+ return isWidth2xl;
31
+ }
32
32
  }
33
33
  export const isWidth2xl = computed(() => bodyWidth.value > breakpoints['2xl']);
34
34
  export const isWidthXl = computed(() => bodyWidth.value > breakpoints.xl);
35
35
  export const isWidthLg = computed(() => bodyWidth.value > breakpoints.lg);
36
36
  export const isWidthMd = computed(() => bodyWidth.value > breakpoints.md);
37
- export const isWidthSm = computed(() => bodyWidth.value > breakpoints.sm);
37
+ export const isWidthSm = computed(() => bodyWidth.value > breakpoints.sm);
@@ -1,4 +1,4 @@
1
- import { defineComponent, reactive, toRef, } from 'vue';
1
+ import { defineComponent, reactive, toRef } from 'vue';
2
2
  /**
3
3
  * Components should be created using this helper function.
4
4
  * It only takes three arguments, the name and the props of the component and the setup function.
@@ -10,7 +10,12 @@ import { defineComponent, reactive, toRef, } from 'vue';
10
10
  * @returns the created vue-component.
11
11
  */
12
12
  export function createComponent(name, props, setup) {
13
- return defineComponent({ name, props, emits: [], setup });
13
+ return defineComponent({
14
+ name,
15
+ props,
16
+ emits: [],
17
+ setup
18
+ });
14
19
  }
15
20
  /**
16
21
  * Views should be created using this helper function. Views are special components, which don't have props.
@@ -21,7 +26,11 @@ export function createComponent(name, props, setup) {
21
26
  * @returns the created vue-component.
22
27
  */
23
28
  export function createView(name, setup) {
24
- return defineComponent({ name, emits: [], setup: (props, context) => setup(context) });
29
+ return defineComponent({
30
+ name,
31
+ emits: [],
32
+ setup: (props, context) => setup(context)
33
+ });
25
34
  }
26
35
  /**
27
36
  * If props are specified outside of the {@link createComponent}
@@ -31,7 +40,7 @@ export function createView(name, setup) {
31
40
  * @returns the created props, with correct typing.
32
41
  */
33
42
  export function createProps(props) {
34
- return props;
43
+ return props;
35
44
  }
36
45
  /**
37
46
  * Extracts props from another prop object and returns a reactive object with the specified props.
@@ -44,8 +53,7 @@ export function createProps(props) {
44
53
  * console.log(childProps) // { title: 'hi' }
45
54
  */
46
55
  export function extractProps(props, ...keys) {
47
- const partial = {};
48
- for (const key of keys)
49
- partial[key] = toRef(props, key);
50
- return reactive(partial);
51
- }
56
+ const partial = {};
57
+ for (const key of keys) partial[key] = toRef(props, key);
58
+ return reactive(partial);
59
+ }
package/utils/deferred.js CHANGED
@@ -3,15 +3,15 @@
3
3
  * @returns promise, resolve and reject
4
4
  */
5
5
  export function deferred() {
6
- let resolve;
7
- let reject;
8
- const promise = new Promise((_resolve, _reject) => {
9
- resolve = _resolve;
10
- reject = _reject;
11
- });
12
- return {
13
- promise,
14
- resolve,
15
- reject,
16
- };
17
- }
6
+ let resolve;
7
+ let reject;
8
+ const promise = new Promise((_resolve, _reject) => {
9
+ resolve = _resolve;
10
+ reject = _reject;
11
+ });
12
+ return {
13
+ promise,
14
+ resolve,
15
+ reject
16
+ };
17
+ }
@@ -6,11 +6,8 @@ import { markReadonly } from './utils';
6
6
  * @returns The first item with the specified `id` or `undefined` if none exists.
7
7
  */
8
8
  function find(array, id) {
9
- const filtered = array.filter(item => item.id === id);
10
- if (filtered.length > 0)
11
- return filtered[0];
12
- else
13
- return undefined;
9
+ const filtered = array.filter(item => item.id === id);
10
+ if (filtered.length > 0) return filtered[0];else return undefined;
14
11
  }
15
12
  /**
16
13
  * Checks if the given array contains an item with the `id`.
@@ -19,11 +16,11 @@ function find(array, id) {
19
16
  * @returns `true` if there is at least one item in the array with the given `id`.
20
17
  */
21
18
  function contains(array, id) {
22
- return find(array, id) !== undefined;
19
+ return find(array, id) !== undefined;
23
20
  }
24
21
  function insertSingle(baseArray, insertItem) {
25
- const index = baseArray.findIndex(item => item.id === insertItem.id);
26
- index === -1 ? baseArray.push(insertItem) : baseArray.splice(index, 1, insertItem);
22
+ const index = baseArray.findIndex(item => item.id === insertItem.id);
23
+ index === -1 ? baseArray.push(insertItem) : baseArray.splice(index, 1, insertItem);
27
24
  }
28
25
  /**
29
26
  * Inserts the items into the given array, replacing items with the same `id`.
@@ -34,8 +31,8 @@ function insertSingle(baseArray, insertItem) {
34
31
  * @returns The reference to the same array, which was passed.
35
32
  */
36
33
  function insert(array, ...insertItems) {
37
- insertItems.forEach(item => insertSingle(array, item));
38
- return array;
34
+ insertItems.forEach(item => insertSingle(array, item));
35
+ return array;
39
36
  }
40
37
  /**
41
38
  * Removes all items with the specified `ids` from the given array.
@@ -44,17 +41,14 @@ function insert(array, ...insertItems) {
44
41
  * @returns The reference to the same array, which was passed.
45
42
  */
46
43
  function remove(array, ...ids) {
47
- ids.forEach(id => {
48
- let noMatches = false;
49
- while (!noMatches) {
50
- const index = array.findIndex(item => item.id === id);
51
- if (index != -1)
52
- array.splice(index, 1);
53
- else
54
- noMatches = true;
55
- }
56
- });
57
- return array;
44
+ ids.forEach(id => {
45
+ let noMatches = false;
46
+ while (!noMatches) {
47
+ const index = array.findIndex(item => item.id === id);
48
+ if (index != -1) array.splice(index, 1);else noMatches = true;
49
+ }
50
+ });
51
+ return array;
58
52
  }
59
53
  /**
60
54
  * Compares the two arrays and checks if they both have
@@ -64,15 +58,19 @@ function remove(array, ...ids) {
64
58
  * @returns `true` if the arrays contain item with the same `ids` in the same order.
65
59
  */
66
60
  function areSameArrays(first, second) {
67
- if (first.length != second.length)
68
- return false;
69
- for (let i = 0; i < first.length; i++) {
70
- if (first[i]?.id !== second[i]?.id)
71
- return false;
72
- }
73
- return true;
61
+ if (first.length != second.length) return false;
62
+ for (let i = 0; i < first.length; i++) {
63
+ if (first[i]?.id !== second[i]?.id) return false;
64
+ }
65
+ return true;
74
66
  }
75
67
  /**
76
68
  * This object contains utility functions to deal with {@link Identifiable} objects.
77
69
  */
78
- export const Id = markReadonly({ find, contains, insert, remove, areSameArrays });
70
+ export const Id = markReadonly({
71
+ find,
72
+ contains,
73
+ insert,
74
+ remove,
75
+ areSameArrays
76
+ });
@@ -5,10 +5,7 @@
5
5
  * @see maxLengthSplitCenter
6
6
  */
7
7
  export function maxLength(input, maxLength) {
8
- if (input && input.length > maxLength)
9
- return `${input.substring(0, maxLength - 3).trim()}...`;
10
- else
11
- return input || '';
8
+ if (input && input.length > maxLength) return `${input.substring(0, maxLength - 3).trim()}...`;else return input || '';
12
9
  }
13
10
  /**
14
11
  * Returns a shortened string with '...' in the center of the string if it is longer than the given `maxLength`.
@@ -17,12 +14,10 @@ export function maxLength(input, maxLength) {
17
14
  * @see maxLength
18
15
  */
19
16
  export function maxLengthSplitCenter(input, maxLength) {
20
- if (input && input.length > maxLength) {
21
- const chars = maxLength - 3;
22
- const charsAtStart = Math.ceil(chars / 2);
23
- const charsAtEnd = Math.floor(chars / 2);
24
- return `${input.substring(0, charsAtStart).trim()}...${input.substring(input.length - charsAtEnd).trim()}`;
25
- }
26
- else
27
- return input || '';
28
- }
17
+ if (input && input.length > maxLength) {
18
+ const chars = maxLength - 3;
19
+ const charsAtStart = Math.ceil(chars / 2);
20
+ const charsAtEnd = Math.floor(chars / 2);
21
+ return `${input.substring(0, charsAtStart).trim()}...${input.substring(input.length - charsAtEnd).trim()}`;
22
+ } else return input || '';
23
+ }
package/utils/tailwind.js CHANGED
@@ -1 +1 @@
1
- export {};
1
+ export {};