@tuspe/components 1.9.7 → 1.9.9

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.
@@ -1,16 +1,14 @@
1
1
  <script lang="ts">
2
2
  import {page} from '$app/state'
3
- import {onMount} from 'svelte'
4
- import {validateArray} from './'
3
+ import {cx, validateArray} from './'
5
4
  import type {Breadcrumb} from './'
6
5
  import type {BreadcrumbView} from './types'
7
6
 
8
7
  let {homeName = 'Etusivu', homeSlug = '', onlyMeta = false, outerClass, values}: BreadcrumbView = $props()
9
- let classes = $state('truncate')
8
+ let classes = $derived(cx('truncate', outerClass))
10
9
 
11
- const origin = page.url.origin + '/'
12
-
13
- let originWithSlug = $state(origin + homeSlug),
10
+ let origin = $derived(page.url.origin + '/'),
11
+ originWithSlug = $derived(origin + homeSlug),
14
12
  listItems = $derived<Breadcrumb[]>(
15
13
  validateArray(values)
16
14
  ? [
@@ -34,12 +32,6 @@
34
32
  ? `<script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":${JSON.stringify(listItems)}}${'<'}/script>`
35
33
  : ''
36
34
  )
37
-
38
- onMount(() => {
39
- if (outerClass) {
40
- classes += ` ${outerClass}`
41
- }
42
- })
43
35
  </script>
44
36
 
45
37
  <svelte:head>
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import {loading} from './'
2
+ import {cx, loading} from './'
3
3
  import type {ButtonView} from './types'
4
4
 
5
5
  let {
@@ -39,49 +39,25 @@
39
39
  value
40
40
  }: ButtonView = $props()
41
41
 
42
- let classes = $state(`btn text-${color}`)
43
-
44
- if (control) {
45
- classes += ' control'
46
- } else {
47
- classes += ' bg-' + colorBg
48
- }
49
- if (borderSize) {
50
- classes += ' border-solid border-' + borderSize + ' border-' + borderColor
51
- }
52
- if (extraClass) {
53
- classes += ' ' + extraClass
54
- }
55
- if (fill) {
56
- classes += ' fill'
57
- }
58
- if (fontWeight) {
59
- classes += ' font-' + fontWeight
60
- }
61
- if (fullWidth) {
62
- classes += ' w-full'
63
- }
64
- if (hover) {
65
- classes += ' hover-' + hover
66
- }
67
- if (hoverText) {
68
- classes += ' hover-text-' + hoverText
69
- }
70
- if (!noCenter) {
71
- classes += ' center'
72
- }
73
- if (noHeight) {
74
- classes += ' no-height'
75
- }
76
- if (noPadding) {
77
- classes += ' no-padding'
78
- }
79
- if (rounded) {
80
- classes += ' radius-' + rounded
81
- }
82
- if (uppercase) {
83
- classes += ' uppercase'
84
- }
42
+ let classes = $derived(
43
+ cx(
44
+ 'btn',
45
+ `text-${color}`,
46
+ control ? 'control' : `bg-${colorBg}`,
47
+ borderSize ? `border-solid border-${borderSize} border-${borderColor}` : false,
48
+ extraClass,
49
+ fill && 'fill',
50
+ fontWeight && `font-${fontWeight}`,
51
+ fullWidth && 'w-full',
52
+ hover && `hover-${hover}`,
53
+ hoverText && `hover-text-${hoverText}`,
54
+ !noCenter && 'center',
55
+ noHeight && 'no-height',
56
+ noPadding && 'no-padding',
57
+ rounded && `radius-${rounded}`,
58
+ uppercase && 'uppercase'
59
+ )
60
+ )
85
61
  </script>
86
62
 
87
63
  {#if href}
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import {loading} from './'
2
+ import {cx, isDisabled, loading} from './'
3
3
  import type {CheckboxView} from './types'
4
4
  let {
5
5
  children,
@@ -13,14 +13,11 @@
13
13
  value,
14
14
  ...props
15
15
  }: CheckboxView = $props()
16
- let classes = $state('input-checkbox')
17
- if (outerClass) {
18
- classes += ` ${outerClass}`
19
- }
16
+ let classes = $derived(cx('input-checkbox', outerClass))
20
17
  </script>
21
18
 
22
19
  <label class={classes}>
23
- <input bind:checked disabled={disabled || $loading ? true : false} {id} {onchange} {required} type="checkbox" {value} {...props} />
20
+ <input bind:checked disabled={isDisabled(disabled, $loading)} {id} {onchange} {required} type="checkbox" {value} {...props} />
24
21
  <span>
25
22
  {@render children?.()}
26
23
  {#if required}<sup>*</sup>{/if}
package/dist/Image.svelte CHANGED
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import {cx} from './'
2
3
  import type {ImageView} from './types'
3
4
  let {
4
5
  ariaHidden,
@@ -14,28 +15,9 @@
14
15
  objectFit
15
16
  }: ImageView = $props()
16
17
 
17
- let classes = $state(display)
18
- if (aspect) {
19
- classes += ` aspect-${aspect}`
20
- }
21
- if (objectFit) {
22
- classes += ' ' + objectFit
23
- }
24
- if (ball) {
25
- classes += ' radius-full'
26
- }
27
- if (border) {
28
- classes += ' border-full'
29
- }
30
- if (center) {
31
- classes += ' mx-auto'
32
- }
33
- if (fullWidth) {
34
- classes += ' full'
35
- }
36
- if (extraClasses) {
37
- classes += ' ' + extraClasses
38
- }
18
+ let classes = $derived(
19
+ cx(display, aspect && `aspect-${aspect}`, objectFit, ball && 'radius-full', border && 'border-full', center && 'mx-auto', fullWidth && 'full', extraClasses)
20
+ )
39
21
  </script>
40
22
 
41
23
  {#if image?.src}
package/dist/Input.svelte CHANGED
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import {loading} from './'
2
+ import {cx, isDisabled, loading} from './'
3
3
  import type {InputView} from './types'
4
4
 
5
5
  let {
@@ -21,20 +21,9 @@
21
21
  ...props
22
22
  }: InputView = $props()
23
23
 
24
- let classesIn = $state(''),
25
- classesOut = $state(`input-${type}`)
26
- if (inputClass) {
27
- classesIn = inputClass
28
- }
29
- if (bgColor && bgColor !== 'none') {
30
- classesIn += ` bg-${bgColor}`
31
- }
32
- if (borderColor && borderColor !== 'none') {
33
- classesIn += ` border-color-${borderColor}`
34
- }
35
- if (outerClass) {
36
- classesOut += ` ${outerClass}`
37
- }
24
+ let classesIn = $derived(cx(inputClass, bgColor !== 'none' && `bg-${bgColor}`, borderColor !== 'none' && `border-color-${borderColor}`)),
25
+ classesOut = $derived(cx(`input-${type}`, outerClass)),
26
+ inputDisabled = $derived(isDisabled(disabled, $loading))
38
27
  </script>
39
28
 
40
29
  <label class={classesOut}>
@@ -44,7 +33,7 @@
44
33
  <textarea
45
34
  bind:value
46
35
  class={classesIn}
47
- disabled={disabled || $loading ? true : false}
36
+ disabled={inputDisabled}
48
37
  {id}
49
38
  maxlength={max ? Number(max) : undefined}
50
39
  {required}
@@ -56,7 +45,7 @@
56
45
  <input
57
46
  bind:value
58
47
  class={classesIn}
59
- disabled={disabled || $loading ? true : false}
48
+ disabled={inputDisabled}
60
49
  lang="fi-FI"
61
50
  {max}
62
51
  {min}
@@ -75,7 +64,7 @@
75
64
  {required}
76
65
  {type}
77
66
  class={classesIn}
78
- disabled={disabled || $loading ? true : false}
67
+ disabled={inputDisabled}
79
68
  maxlength={max ? Number(max) : undefined}
80
69
  minlength={min ? Number(min) : undefined}
81
70
  onkeyup={onchange}
@@ -1,29 +1,14 @@
1
1
  <script lang="ts">
2
- import {loading} from './'
2
+ import {cx, isDisabled, loading} from './'
3
3
  import type {SelectView} from './types'
4
- let {
5
- colorBg = 'bg-transparent',
6
- disabled,
7
- id,
8
- innerClass,
9
- label,
10
- onchange,
11
- outerClass,
12
- placeholder,
13
- required = false,
14
- value = $bindable(),
15
- values
16
- }: SelectView = $props()
17
- let classes = $state(colorBg)
18
- if (innerClass) {
19
- classes += ' ' + innerClass
20
- }
4
+ let {colorBg = 'bg-transparent', disabled, id, innerClass, label, onchange, outerClass, placeholder, required = false, value = $bindable(), values}: SelectView = $props()
5
+ let classes = $derived(cx(colorBg, innerClass))
21
6
  </script>
22
7
 
23
8
  <label class={outerClass}>
24
9
  {label}
25
10
  {#if required}<sup>*</sup>{/if}
26
- <select bind:value {onchange} class={classes} disabled={disabled || $loading ? true : false} {id} {placeholder} {required}>
11
+ <select bind:value {onchange} class={classes} disabled={isDisabled(disabled, $loading)} {id} {placeholder} {required}>
27
12
  {#each values as item}
28
13
  <option value={item.value}>{item.name}</option>
29
14
  {/each}
@@ -32,8 +17,8 @@
32
17
 
33
18
  <style scoped>
34
19
  select {
35
- background: url(data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0Ljk1IDEwIj48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjt9LmNscy0ye2ZpbGw6IzQ0NDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPmFycm93czwvdGl0bGU+PHJlY3QgY2xhc3M9ImNscy0xIiB3aWR0aD0iNC45NSIgaGVpZ2h0PSIxMCIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSIxLjQxIDQuNjcgMi40OCAzLjE4IDMuNTQgNC42NyAxLjQxIDQuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iMy41NCA1LjMzIDIuNDggNi44MiAxLjQxIDUuMzMgMy41NCA1LjMzIi8+PC9zdmc+)
36
- no-repeat 98% 50%;
20
+ background: url(data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0Ljk1IDEwIj48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjt9LmNscy0ye2ZpbGw6IzQ0NDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPmFycm93czwvdGl0bGU+PHJlY3QgY2xhc3M9ImNscy0xIiB3aWR0aD0iNC45NSIgaGVpZ2h0PSIxMCIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSIxLjQxIDQuNjcgMi40OCAzLjE4IDMuNTQgNC42NyAxLjQxIDQuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iMy41NCA1LjMzIDIuNDggNi44MiAxLjQxIDUuMzMgMy41NCA1LjMzIi8+PC9zdmc+) no-repeat 98% 50%;
21
+ background-color: initial;
37
22
  border-radius: 0.375rem;
38
23
  border: 1px solid var(--color-border);
39
24
  color: var(--color-content);
@@ -47,10 +32,6 @@
47
32
  appearance: none;
48
33
  }
49
34
 
50
- select.bg-transparent {
51
- background-color: transparent;
52
- }
53
-
54
35
  select:disabled {
55
36
  cursor: not-allowed;
56
37
  opacity: 0.6;
package/dist/index.d.ts CHANGED
@@ -26,6 +26,14 @@ export interface SelectItem {
26
26
  value: number | string;
27
27
  }
28
28
  export declare const loading: import("svelte/store").Writable<number>;
29
+ /**
30
+ * CLASS NAMES
31
+ */
32
+ export declare const cx: (...classes: (string | false | null | undefined)[]) => string;
33
+ /**
34
+ * DISABLED STATE
35
+ */
36
+ export declare const isDisabled: (disabled: boolean | undefined, loadingCount: number) => boolean;
29
37
  /**
30
38
  * PRICES AND NUMBERS
31
39
  */
package/dist/index.js CHANGED
@@ -11,6 +11,14 @@ import Modal from './Modal.svelte';
11
11
  import Select from './Select.svelte';
12
12
  export { Breadcrumbs, Button, ButtonArrow, ButtonClose, ButtonMenu, Checkbox, Image, Input, Modal, Select };
13
13
  export const loading = writable(0);
14
+ /**
15
+ * CLASS NAMES
16
+ */
17
+ export const cx = (...classes) => classes.filter(Boolean).join(' ');
18
+ /**
19
+ * DISABLED STATE
20
+ */
21
+ export const isDisabled = (disabled, loadingCount) => disabled === true || loadingCount > 0;
14
22
  /**
15
23
  * PRICES AND NUMBERS
16
24
  */
@@ -61,20 +69,20 @@ export const slugify = (value) => {
61
69
  .replace(/^-+|-+$/g, ''); // Trim leading and trailing hyphens
62
70
  };
63
71
  export const validateSlug = (value) => {
64
- return value && slugify(value) === value ? true : false;
72
+ return !!value && slugify(value) === value;
65
73
  };
66
74
  export const validateEmail = (email) => {
67
- var re = /\S+@\S+\.\S+/;
75
+ const re = /\S+@\S+\.\S+/;
68
76
  return re.test(email);
69
77
  };
70
78
  export const validateString = (value) => {
71
- return value && value.replace(/[^\w\s@!.:;,?+äÄöÖåÅ/%&()|-]/gi, '') === value ? true : false;
79
+ return !!value && value.replace(/[^\w\s@!.:;,?+äÄöÖåÅ/%&()|-]/gi, '') === value;
72
80
  };
73
81
  /**
74
82
  * ARRAY VALIDATIONS
75
83
  */
76
84
  export const validateArray = (value, items = 0) => {
77
- return value && Array.isArray(value) && value.length > items ? true : false;
85
+ return Array.isArray(value) && value.length > items;
78
86
  };
79
87
  export const cacheValues = writable({});
80
88
  export const handleCache = (key, value = undefined, ttl = 60) => {
package/dist/types.d.ts CHANGED
@@ -19,7 +19,6 @@ export interface ButtonCloseView {
19
19
  ariaLabel?: string;
20
20
  color?: string;
21
21
  hover?: 'black' | 'primary' | 'secondary' | 'success' | 'transparent';
22
- hoverText?: 'black' | 'primary' | 'secondary' | 'white';
23
22
  id?: string;
24
23
  }
25
24
  export interface ButtonMenuView {
@@ -114,7 +113,6 @@ export interface ModalView {
114
113
  children: Snippet;
115
114
  buttonAriaLabel?: string;
116
115
  colorButton?: string;
117
- colorBg?: string;
118
116
  headerClass?: string;
119
117
  innerClass?: string;
120
118
  open?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuspe/components",
3
- "version": "1.9.7",
3
+ "version": "1.9.9",
4
4
  "description": "A reusable SvelteKit component library for form elements, breadcrumbs, prices and images.",
5
5
  "keywords": [
6
6
  "svelteKit",
@@ -27,6 +27,19 @@
27
27
  "type": "git",
28
28
  "url": "git+https://github.com/TuspeDesign/svelte-components.git"
29
29
  },
30
+ "scripts": {
31
+ "dev": "vite dev",
32
+ "build": "vite build && npm run prepack",
33
+ "preview": "vite preview",
34
+ "prepare": "svelte-kit sync",
35
+ "prepack": "svelte-kit sync && svelte-package",
36
+ "publint": "publint .",
37
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
38
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
39
+ "format": "prettier --write .",
40
+ "lint": "prettier --check . && eslint .",
41
+ "publish": "npm publish --access public"
42
+ },
30
43
  "files": [
31
44
  "dist",
32
45
  "!dist/**/*.test.*",
@@ -47,34 +60,24 @@
47
60
  "svelte": "^5.20.2"
48
61
  },
49
62
  "devDependencies": {
50
- "@eslint/compat": "^2.0.0",
51
- "@eslint/js": "^9.39.1",
63
+ "@eslint/compat": "^2.1.0",
64
+ "@eslint/js": "^10.0.1",
52
65
  "@sveltejs/adapter-static": "^3.0.10",
53
- "@sveltejs/enhanced-img": "^0.9.0",
54
- "@sveltejs/kit": "^2.49.0",
55
- "@sveltejs/package": "^2.5.6",
56
- "@sveltejs/vite-plugin-svelte": "^6.2.1",
57
- "eslint": "^9.39.1",
66
+ "@sveltejs/enhanced-img": "^0.10.4",
67
+ "@sveltejs/kit": "^2.65.0",
68
+ "@sveltejs/package": "^2.5.8",
69
+ "@sveltejs/vite-plugin-svelte": "^7.1.2",
70
+ "eslint": "^10.4.1",
58
71
  "eslint-config-prettier": "^10.1.8",
59
- "eslint-plugin-svelte": "^3.13.0",
60
- "globals": "^16.5.0",
61
- "prettier": "^3.6.2",
62
- "prettier-plugin-svelte": "^3.4.0",
63
- "publint": "^0.3.15",
64
- "svelte": "^5.43.14",
65
- "svelte-check": "^4.3.4",
66
- "typescript": "^5.9.3",
67
- "typescript-eslint": "^8.47.0",
68
- "vite": "^7.2.4"
69
- },
70
- "scripts": {
71
- "dev": "vite dev",
72
- "build": "vite build && npm run prepack",
73
- "preview": "vite preview",
74
- "publint": "publint .",
75
- "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
76
- "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
77
- "format": "prettier --write .",
78
- "lint": "prettier --check . && eslint ."
72
+ "eslint-plugin-svelte": "^3.19.0",
73
+ "globals": "^17.6.0",
74
+ "prettier": "^3.8.4",
75
+ "prettier-plugin-svelte": "^4.1.0",
76
+ "publint": "^0.3.21",
77
+ "svelte": "^5.56.3",
78
+ "svelte-check": "^4.6.0",
79
+ "typescript": "^6.0.3",
80
+ "typescript-eslint": "^8.61.0",
81
+ "vite": "^8.0.16"
79
82
  }
80
83
  }