webcoreui 0.1.0 → 0.2.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 (66) hide show
  1. package/README.md +29 -1
  2. package/astro.d.ts +4 -0
  3. package/astro.js +4 -0
  4. package/components/Accordion/accordion.module.scss +1 -2
  5. package/components/Alert/alert.module.scss +3 -3
  6. package/components/Badge/badge.module.scss +1 -1
  7. package/components/Button/button.module.scss +2 -2
  8. package/components/Button/button.ts +1 -1
  9. package/components/Card/card.module.scss +0 -1
  10. package/components/Checkbox/checkbox.module.scss +4 -4
  11. package/components/Icon/map.ts +2 -0
  12. package/components/Input/input.module.scss +2 -2
  13. package/components/Menu/Menu.astro +7 -3
  14. package/components/Menu/Menu.svelte +11 -3
  15. package/components/Menu/Menu.tsx +7 -1
  16. package/components/Menu/menu.module.scss +4 -1
  17. package/components/Menu/menu.ts +1 -0
  18. package/components/Modal/Modal.astro +70 -0
  19. package/components/Modal/Modal.svelte +71 -0
  20. package/components/Modal/Modal.tsx +76 -0
  21. package/components/Modal/modal.module.scss +103 -0
  22. package/components/Modal/modal.ts +18 -0
  23. package/components/Progress/progress.module.scss +3 -3
  24. package/components/Radio/radio.module.scss +1 -2
  25. package/components/Rating/Rating.astro +2 -2
  26. package/components/Rating/Rating.svelte +2 -2
  27. package/components/Rating/Rating.tsx +2 -2
  28. package/components/Rating/rating.module.scss +1 -1
  29. package/components/Slider/Slider.astro +44 -0
  30. package/components/Slider/Slider.svelte +42 -0
  31. package/components/Slider/Slider.tsx +48 -0
  32. package/components/Slider/slider.module.scss +68 -0
  33. package/components/Slider/slider.ts +20 -0
  34. package/components/Switch/switch.module.scss +1 -1
  35. package/components/Table/Table.astro +6 -1
  36. package/components/Table/Table.svelte +3 -1
  37. package/components/Table/Table.tsx +7 -1
  38. package/components/Table/table.module.scss +11 -1
  39. package/components/Table/table.ts +1 -0
  40. package/components/Tabs/tabs.module.scss +6 -1
  41. package/components/ThemeSwitcher/ThemeSwitcher.astro +1 -0
  42. package/components/ThemeSwitcher/ThemeSwitcher.svelte +2 -1
  43. package/components/ThemeSwitcher/ThemeSwitcher.tsx +2 -1
  44. package/components/Timeline/timeline.module.scss +4 -4
  45. package/components/TimelineItem/TimelineItem.tsx +1 -6
  46. package/components/TimelineItem/timelineitem.module.scss +2 -3
  47. package/components/TimelineItem/timelineitem.ts +5 -0
  48. package/icons/close.svg +3 -0
  49. package/icons.d.ts +1 -0
  50. package/icons.js +1 -0
  51. package/index.js +2 -0
  52. package/package.json +1 -1
  53. package/react.d.ts +6 -2
  54. package/react.js +4 -0
  55. package/scss/config/color-palette.scss +1 -0
  56. package/scss/config/mixins.scss +152 -155
  57. package/scss/config/typography.scss +8 -9
  58. package/scss/global/theme.scss +71 -38
  59. package/scss/global/tooltip.scss +5 -3
  60. package/scss/global/utility.scss +76 -58
  61. package/scss/resets.scss +10 -5
  62. package/scss/setup.scss +2 -2
  63. package/svelte.d.ts +4 -0
  64. package/svelte.js +4 -0
  65. package/utils/interpolate.ts +23 -0
  66. package/utils/modal.ts +59 -0
@@ -0,0 +1,103 @@
1
+ @import '../../scss/config.scss';
2
+
3
+ .modal {
4
+ @include transition();
5
+ @include position(fixed, 't50%', 'l50%');
6
+ @include spacing(0, p-default);
7
+ @include layer(modal);
8
+ @include visibility(block, 0);
9
+ @include border(primary-50);
10
+ @include background(primary-70);
11
+ @include typography(primary);
12
+ @include border-radius(md);
13
+ @include size('w90%');
14
+
15
+ transform: translate(-50%, calc(-50% + 15px));
16
+ max-width: 500px;
17
+ pointer-events: none;
18
+
19
+ &[data-show="true"] {
20
+ @include visibility(1);
21
+
22
+ transform: translate(-50%, -50%);
23
+ pointer-events: all;
24
+
25
+ + .overlay {
26
+ @include visibility(1);
27
+ pointer-events: all;
28
+ }
29
+ }
30
+
31
+ .close {
32
+ @include position(absolute, t10px, r10px);
33
+ @include spacing(p-xs);
34
+
35
+ svg {
36
+ @include size(10px);
37
+ }
38
+ }
39
+
40
+ .title {
41
+ @include typography(lg);
42
+ @include spacing(mb-xs);
43
+ @include layout(flex, v-center, xs);
44
+
45
+ svg {
46
+ @include size(20px);
47
+ }
48
+ }
49
+
50
+ .subTitle {
51
+ @include typography(primary-20);
52
+ @include spacing(mb-xs);
53
+ }
54
+
55
+ &.info {
56
+ @include border(info);
57
+
58
+ .title {
59
+ @include typography(info);
60
+ }
61
+ }
62
+
63
+ &.success {
64
+ @include border(success);
65
+
66
+ .title {
67
+ @include typography(success);
68
+ }
69
+ }
70
+
71
+ &.warning {
72
+ @include border(warning);
73
+
74
+ .title {
75
+ @include typography(warning);
76
+ }
77
+ }
78
+
79
+ &.alert {
80
+ @include border(alert);
81
+
82
+ .title {
83
+ @include typography(alert);
84
+ }
85
+ }
86
+ }
87
+
88
+ .overlay {
89
+ @include transition(opacity);
90
+ @include position(fixed);
91
+ @include background(overlay);
92
+ @include layer(header);
93
+ @include visibility(0);
94
+
95
+ inset: 0;
96
+ pointer-events: none;
97
+ }
98
+
99
+ @include media(xs) {
100
+ .modal {
101
+ @include size('wauto');
102
+ }
103
+ }
@@ -0,0 +1,18 @@
1
+ export type ModalProps = {
2
+ title?: string
3
+ subTitle?: string
4
+ showCloseIcon?: boolean
5
+ closeOnEsc?: boolean
6
+ closeOnOverlay?: boolean
7
+ id?: string
8
+ className?: string
9
+ theme?: 'info'
10
+ | 'success'
11
+ | 'warning'
12
+ | 'alert'
13
+ | null
14
+ }
15
+
16
+ export type ReactModalProps = {
17
+ children?: React.ReactNode
18
+ } & ModalProps
@@ -11,19 +11,19 @@ body {
11
11
  @include size('w100%', h10px);
12
12
  @include border-radius(xl);
13
13
  @include visibility(hidden);
14
- @include typography(bold, xxs);
14
+ @include typography(bold, xs);
15
15
  @include background(var(--w-progress-background));
16
16
 
17
17
  color: var(--w-progress-background);
18
18
 
19
19
  &.medium {
20
20
  @include size(h15px);
21
- @include typography(xs);
21
+ @include typography(sm);
22
22
  }
23
23
 
24
24
  &.large {
25
25
  @include size(h20px);
26
- @include typography(sm);
26
+ @include typography(md);
27
27
  }
28
28
 
29
29
  &.square {
@@ -13,7 +13,6 @@ body {
13
13
 
14
14
  label {
15
15
  @include layout(flex, xs);
16
- @include typography(md);
17
16
 
18
17
  cursor: pointer;
19
18
 
@@ -71,7 +70,7 @@ body {
71
70
 
72
71
  .subtext {
73
72
  @include spacing(ml-lg);
74
- @include typography(sm, primary-20);
73
+ @include typography(md, primary-20);
75
74
 
76
75
  a {
77
76
  @include typography(primary-20);
@@ -45,11 +45,11 @@ const translatedReviewText = reviewText.replace('{0}', `${reviewCount}`)
45
45
 
46
46
  <span class:list={classes} style={styleVariables}>
47
47
  {score > 0 && (
48
- <span class={styles.score}>{Array(score).fill('★').join('')}</span>
48
+ <span class={styles.score}>{Array(Math.round(score)).fill('★').join('')}</span>
49
49
  )}
50
50
  {showEmpty && (
51
51
  <span class={styles.empty}>
52
- {Array(total - score).fill('★').join('')}
52
+ {Array(total - Math.round(score)).fill('★').join('')}
53
53
  </span>
54
54
  )}
55
55
  {showText && (
@@ -42,11 +42,11 @@
42
42
 
43
43
  <span class={classes} style={styleVariables}>
44
44
  {#if score}
45
- <span class={styles.score}>{Array(score).fill('★').join('')}</span>
45
+ <span class={styles.score}>{Array(Math.round(score)).fill('★').join('')}</span>
46
46
  {/if}
47
47
  {#if showEmpty}
48
48
  <span class={styles.empty}>
49
- {Array((total || 5) - score).fill('★').join('')}
49
+ {Array((total || 5) - Math.round(score)).fill('★').join('')}
50
50
  </span>
51
51
  {/if}
52
52
 
@@ -43,12 +43,12 @@ const Rating = ({
43
43
  <span className={classes} style={styleVariables}>
44
44
  {score > 0 && (
45
45
  <span className={styles.score}>
46
- {Array(score).fill('★').join('')}
46
+ {Array(Math.round(score)).fill('★').join('')}
47
47
  </span>
48
48
  )}
49
49
  {showEmpty && (
50
50
  <span className={styles.empty}>
51
- {Array(total - score).fill('★').join('')}
51
+ {Array(total - Math.round(score)).fill('★').join('')}
52
52
  </span>
53
53
  )}
54
54
  {showText && (
@@ -35,7 +35,7 @@ body {
35
35
 
36
36
  .text {
37
37
  @include transition(color);
38
- @include typography(md, primary-20);
38
+ @include typography(default, primary-20);
39
39
  @include spacing(ml-xs);
40
40
 
41
41
  &.m {
@@ -0,0 +1,44 @@
1
+ ---
2
+ import type { SliderProps } from './slider'
3
+
4
+ import styles from './slider.module.scss'
5
+ import { classNames } from '../../utils/classNames'
6
+
7
+ interface Props extends SliderProps {}
8
+
9
+ const {
10
+ min,
11
+ max,
12
+ value,
13
+ step,
14
+ disabled,
15
+ color,
16
+ background,
17
+ thumb,
18
+ id,
19
+ className
20
+ } = Astro.props
21
+
22
+ const classes = [
23
+ styles.slider,
24
+ className
25
+ ]
26
+
27
+ const styleVariables = classNames([
28
+ color && `--w-slider-color: ${color};`,
29
+ background && `--w-slider-background: ${background};`,
30
+ thumb && `--w-slider-thumb: ${thumb};`
31
+ ])
32
+ ---
33
+
34
+ <input
35
+ type="range"
36
+ min={min}
37
+ max={max}
38
+ value={value || min}
39
+ step={step}
40
+ disabled={disabled}
41
+ class:list={classes}
42
+ id={id}
43
+ style={styleVariables}
44
+ />
@@ -0,0 +1,42 @@
1
+ <script lang="ts">
2
+ import type { SvelteSliderProps } from './slider'
3
+
4
+ import styles from './slider.module.scss'
5
+ import { classNames } from '../../utils/classNames'
6
+
7
+ export let min: SvelteSliderProps['min'] = 0
8
+ export let max: SvelteSliderProps['max'] = 100
9
+ export let value: SvelteSliderProps['value'] = 0
10
+ export let step: SvelteSliderProps['step'] = 1
11
+ export let disabled: SvelteSliderProps['disabled'] = false
12
+ export let color: SvelteSliderProps['color'] = ''
13
+ export let background: SvelteSliderProps['background'] = ''
14
+ export let thumb: SvelteSliderProps['thumb'] = ''
15
+ export let id: SvelteSliderProps['id'] = ''
16
+ export let className: SvelteSliderProps['className'] = ''
17
+ export let onChange: SvelteSliderProps['onChange'] = () => {}
18
+
19
+ const classes = classNames([
20
+ styles.slider,
21
+ className
22
+ ])
23
+
24
+ const styleVariables = classNames([
25
+ color && `--w-slider-color: ${color};`,
26
+ background && `--w-slider-background: ${background};`,
27
+ thumb && `--w-slider-thumb: ${thumb};`
28
+ ])
29
+ </script>
30
+
31
+ <input
32
+ type="range"
33
+ min={min}
34
+ max={max}
35
+ value={value || min}
36
+ step={step}
37
+ disabled={disabled}
38
+ class={classes}
39
+ id={id || null}
40
+ style={styleVariables || null}
41
+ on:change={onChange}
42
+ />
@@ -0,0 +1,48 @@
1
+ import React from 'react'
2
+ import type { ReactSliderProps } from './slider'
3
+
4
+ import styles from './slider.module.scss'
5
+ import { classNames } from '../../utils/classNames'
6
+
7
+ const Slider = ({
8
+ min,
9
+ max,
10
+ value,
11
+ step,
12
+ disabled,
13
+ color,
14
+ background,
15
+ thumb,
16
+ id,
17
+ className,
18
+ onChange
19
+ }: ReactSliderProps) => {
20
+ const classes = classNames([
21
+ styles.slider,
22
+ className
23
+ ])
24
+
25
+ const styleVariables = {
26
+ ...(color && { '--w-slider-color': color }),
27
+ ...(background && { '--w-slider-background': background }),
28
+ ...(thumb && { '--w-slider-thumb': thumb })
29
+ } as React.CSSProperties
30
+
31
+ return (
32
+ <input
33
+ type="range"
34
+ min={min}
35
+ max={max}
36
+ defaultValue={value || min}
37
+ step={step}
38
+ disabled={disabled}
39
+ className={classes}
40
+ id={id}
41
+ style={styleVariables}
42
+ onChange={onChange}
43
+ />
44
+
45
+ )
46
+ }
47
+
48
+ export default Slider
@@ -0,0 +1,68 @@
1
+ @import '../../scss/config.scss';
2
+
3
+ body {
4
+ --w-slider-background: var(--w-color-primary-50);
5
+ --w-slider-color: var(--w-color-primary);
6
+ --w-slider-thumb: var(--w-color-primary-50);
7
+ }
8
+
9
+ .slider {
10
+ @include border-radius(xl);
11
+ @include size('w100%');
12
+ @include visibility(hidden);
13
+ @include size(h10px);
14
+ @include spacing(m0);
15
+
16
+ -webkit-appearance: none;
17
+ appearance: none;
18
+ cursor: pointer;
19
+
20
+ &[disabled]::-webkit-slider-runnable-track {
21
+ @include background(primary-50);
22
+ }
23
+
24
+ &[disabled]::-moz-range-track {
25
+ @include background(primary-50);
26
+ }
27
+
28
+ &[disabled]::-webkit-slider-thumb {
29
+ @include background(primary-50);
30
+ @include border(primary-30);
31
+ box-shadow: -995px 0 0 990px var(--w-color-primary-30);
32
+ }
33
+
34
+ &[disabled]::-moz-range-thumb {
35
+ @include background(primary-50);
36
+ @include border(primary-30);
37
+ box-shadow: -995px 0 0 990px var(--w-color-primary-30);
38
+ }
39
+ }
40
+
41
+ .slider::-webkit-slider-runnable-track {
42
+ @include background(var(--w-slider-background));
43
+ }
44
+
45
+ .slider::-moz-range-track {
46
+ @include background(var(--w-slider-background));
47
+ @include size(h10px);
48
+ }
49
+
50
+ .slider::-webkit-slider-thumb {
51
+ @include background(var(--w-slider-thumb));
52
+ @include size(10px);
53
+ @include border-radius(max);
54
+ @include border(var(--w-slider-color));
55
+
56
+ -webkit-appearance: none;
57
+ appearance: none;
58
+ box-shadow: -995px 0 0 990px var(--w-slider-color);
59
+ }
60
+
61
+ .slider::-moz-range-thumb {
62
+ @include background(var(--w-slider-thumb));
63
+ @include size(9px);
64
+ @include border-radius(max);
65
+ @include border(var(--w-slider-color));
66
+
67
+ box-shadow: -995px 0 0 990px var(--w-slider-color);
68
+ }
@@ -0,0 +1,20 @@
1
+ export type SliderProps = {
2
+ min: number
3
+ max: number
4
+ value?: number
5
+ step?: number
6
+ disabled?: boolean
7
+ color?: string
8
+ background?: string
9
+ thumb?: string
10
+ id?: string
11
+ className?: string
12
+ }
13
+
14
+ export type SvelteSliderProps = {
15
+ onChange?: (e: any) => any
16
+ } & SliderProps
17
+
18
+ export type ReactSliderProps = {
19
+ onChange?: (e: any) => any
20
+ } & SliderProps
@@ -36,7 +36,7 @@ body {
36
36
  }
37
37
 
38
38
  .label {
39
- @include typography(sm);
39
+ @include typography(md);
40
40
  }
41
41
  }
42
42
 
@@ -12,6 +12,7 @@ const {
12
12
  striped,
13
13
  offsetStripe,
14
14
  compact,
15
+ maxHeight,
15
16
  className
16
17
  } = Astro.props
17
18
 
@@ -21,11 +22,15 @@ const classes = [
21
22
  striped && styles[`striped-${striped}s`],
22
23
  offsetStripe && styles.offset,
23
24
  compact && styles.compact,
25
+ maxHeight && styles.scroll,
24
26
  className
25
27
  ]
26
28
  ---
27
29
 
28
- <div class:list={classes}>
30
+ <div
31
+ class:list={classes}
32
+ style={maxHeight ? `max-height:${maxHeight}` : undefined}
33
+ >
29
34
  <table>
30
35
  {headings?.length && (
31
36
  <thead>
@@ -11,6 +11,7 @@
11
11
  export let striped: TableProps['striped'] = null
12
12
  export let offsetStripe: TableProps['offsetStripe'] = false
13
13
  export let compact: TableProps['compact'] = false
14
+ export let maxHeight: TableProps['maxHeight'] = 0
14
15
  export let className: TableProps['className'] = ''
15
16
 
16
17
  const classes = classNames([
@@ -19,11 +20,12 @@
19
20
  striped && styles[`striped-${striped}s`],
20
21
  offsetStripe && styles.offset,
21
22
  compact && styles.compact,
23
+ maxHeight && styles.scroll,
22
24
  className
23
25
  ])
24
26
  </script>
25
27
 
26
- <div class={classes}>
28
+ <div class={classes} style={maxHeight ? `max-height:${maxHeight}` : null}>
27
29
  <table>
28
30
  {#if headings?.length}
29
31
  <thead>
@@ -12,6 +12,7 @@ const Table = ({
12
12
  striped,
13
13
  offsetStripe,
14
14
  compact,
15
+ maxHeight,
15
16
  className
16
17
  }: TableProps) => {
17
18
  const classes = classNames([
@@ -20,11 +21,16 @@ const Table = ({
20
21
  striped && styles[`striped-${striped}s`],
21
22
  offsetStripe && styles.offset,
22
23
  compact && styles.compact,
24
+ maxHeight && styles.scroll,
23
25
  className
24
26
  ])
25
27
 
28
+ const styleVariables = {
29
+ ...(maxHeight && { 'max-height': maxHeight })
30
+ } as React.CSSProperties
31
+
26
32
  return (
27
- <div className={classes}>
33
+ <div className={classes} style={styleVariables}>
28
34
  <table>
29
35
  {headings?.length && (
30
36
  <thead>
@@ -5,7 +5,7 @@
5
5
 
6
6
  table {
7
7
  @include size('w100%');
8
- @include typography(md, left);
8
+ @include typography(left);
9
9
 
10
10
  border-collapse: collapse;
11
11
  }
@@ -57,4 +57,14 @@
57
57
  @include spacing(py-xxs, px-sm);
58
58
  }
59
59
  }
60
+
61
+ &.scroll {
62
+ @include spacing(pr-sm);
63
+
64
+ thead {
65
+ @include position(sticky, t0);
66
+ @include background(primary-70);
67
+ box-shadow: 0 .5px 0 var(--w-color-primary-50);
68
+ }
69
+ }
60
70
  }
@@ -6,5 +6,6 @@ export type TableProps = {
6
6
  striped?: 'column' | 'row' | null
7
7
  offsetStripe?: boolean
8
8
  compact?: boolean
9
+ maxHeight?: number
9
10
  className?: string
10
11
  }
@@ -7,6 +7,7 @@
7
7
  @include border-radius(md);
8
8
  @include spacing(p-xs);
9
9
  @include size(wmax-content);
10
+ @include border(0);
10
11
 
11
12
  button {
12
13
  @include transition();
@@ -46,6 +47,10 @@
46
47
  &.outline .items button {
47
48
  @include border(bottom, 0);
48
49
  }
50
+
51
+ &:not(.outline) .items {
52
+ @include border(0);
53
+ }
49
54
 
50
55
  .items {
51
56
  @include layout(column, xs);
@@ -76,7 +81,7 @@
76
81
  button {
77
82
  @include transition(color);
78
83
  @include background(transparent);
79
- @include typography(md, primary-20);
84
+ @include typography(default, primary-20);
80
85
  @include border(0);
81
86
  @include spacing(p-md);
82
87
  @include layout(flex, v-center, sm);
@@ -38,6 +38,7 @@ const buttonClasses = [
38
38
  <button
39
39
  style={!useIcons ? `background:${theme};` : undefined}
40
40
  data-theme={themes[theme]}
41
+ aria-label={themes[theme]}
41
42
  class:list={buttonClasses}
42
43
  >
43
44
  {index === 0 && <slot name="primaryIcon" />}
@@ -61,9 +61,10 @@
61
61
  >
62
62
  {#each Object.keys(themes) as theme, index}
63
63
  <button
64
+ on:click={() => setTheme(toggle ? index : themes[theme])}
64
65
  style={!useIcons ? `background:${theme};` : undefined}
65
66
  data-active={currentTheme === themes[theme]}
66
- on:click={() => setTheme(toggle ? index : themes[theme])}
67
+ aria-label={themes[theme]}
67
68
  class={classNames([
68
69
  styles.switch,
69
70
  useIcons && styles.icons
@@ -70,8 +70,9 @@ const ThemeSwitcher = ({
70
70
  {Object.keys(themes as {}).map((theme, index) => (
71
71
  <button
72
72
  key={index}
73
- data-active={currentTheme === themes[theme]}
74
73
  onClick={() => setTheme(toggle ? index : themes[theme])}
74
+ data-active={currentTheme === themes[theme]}
75
+ aria-label={themes[theme]}
75
76
  style={!useIcons ? { background: theme } : undefined}
76
77
  className={classNames([
77
78
  styles.switch,
@@ -28,11 +28,11 @@ body {
28
28
  left: $leftOffset
29
29
  }
30
30
 
31
- &.fill li::before {
31
+ &.fill > li::before {
32
32
  content: '';
33
33
  }
34
34
 
35
- &.stroke li::before {
35
+ &.stroke > li::before {
36
36
  @include background(primary-70);
37
37
  border: 2px solid var(--w-timeline-color);
38
38
  }
@@ -47,7 +47,7 @@ body {
47
47
  left: calc(50% - 1px);
48
48
  }
49
49
 
50
- li {
50
+ > li {
51
51
  @include size('w50%');
52
52
 
53
53
  &:nth-child(odd) {
@@ -69,7 +69,7 @@ body {
69
69
  }
70
70
  }
71
71
 
72
- &.centered li:nth-child(odd) {
72
+ &.centered > li:nth-child(odd) {
73
73
  @include typography(right);
74
74
  }
75
75
  }
@@ -1,14 +1,9 @@
1
1
  import React from 'react'
2
- import type { TimelineItemProps } from './timelineitem'
2
+ import type { ReactTimelineItemProps } from './timelineitem'
3
3
 
4
4
  import styles from './timelineitem.module.scss'
5
5
  import { classNames } from '../../utils/classNames'
6
6
 
7
- type ReactTimelineItemProps = {
8
- TitleTag?: keyof JSX.IntrinsicElements
9
- children: React.ReactNode
10
- } & Omit<TimelineItemProps, 'titleTag'>
11
-
12
7
  const TimelineItem = ({
13
8
  title,
14
9
  TitleTag = 'span',