@globalbrain/sefirot 0.65.0 → 0.68.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 (52) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +5 -17
  3. package/lib/.DS_Store +0 -0
  4. package/lib/assets/styles/variables.css +345 -5
  5. package/lib/components/.DS_Store +0 -0
  6. package/lib/components/SButton.vue +22 -27
  7. package/lib/components/SButtonGroup.vue +40 -22
  8. package/lib/components/SDialog.vue +4 -3
  9. package/lib/components/SInputBase.vue +27 -5
  10. package/lib/components/SInputNumber.vue +18 -1
  11. package/lib/components/SInputRadio.vue +5 -4
  12. package/lib/components/SInputText.vue +176 -19
  13. package/lib/components/SInputTextarea.vue +13 -2
  14. package/lib/components/SInputYMD.vue +244 -0
  15. package/lib/components/SModal.vue +7 -2
  16. package/lib/components/SSheet.vue +47 -0
  17. package/lib/components/SSheetFooter.vue +14 -0
  18. package/lib/components/SSheetFooterAction.vue +32 -0
  19. package/lib/components/SSheetFooterActions.vue +19 -0
  20. package/lib/components/SSheetHeader.vue +75 -0
  21. package/lib/components/SSheetHeaderTitle.vue +17 -0
  22. package/lib/components/SSheetMedium.vue +92 -0
  23. package/lib/components/SSnackbar.vue +7 -2
  24. package/lib/components/icons/.DS_Store +0 -0
  25. package/lib/components/icons/SIconGrab.vue +10 -0
  26. package/lib/components/icons/SIconInbox.vue +5 -0
  27. package/lib/components/icons/SIconLock.vue +5 -0
  28. package/lib/components/icons/SIconMoreVertical.vue +7 -0
  29. package/lib/components/icons/SIconPreloader.vue +239 -0
  30. package/lib/composables/Modal.ts +16 -5
  31. package/lib/composables/Tooltip.ts +1 -1
  32. package/lib/mixins/Sheet.ts +22 -0
  33. package/lib/validation/rules/every.ts +38 -0
  34. package/lib/validation/rules/index.ts +13 -1
  35. package/lib/validation/rules/requiredMonthDate.ts +11 -0
  36. package/lib/validation/rules/requiredYearMonth.ts +11 -0
  37. package/lib/validation/rules/requiredYearMonthDate.ts +11 -0
  38. package/lib/validation/rules/yearMonth.ts +11 -0
  39. package/lib/validation/rules/yearMonthDate.ts +11 -0
  40. package/lib/validation/validators/index.ts +13 -1
  41. package/lib/validation/validators/monthDate.ts +20 -0
  42. package/lib/validation/validators/requiredMonthDate.ts +8 -0
  43. package/lib/validation/validators/requiredYearMonth.ts +8 -0
  44. package/lib/validation/validators/requiredYearMonthDate.ts +9 -0
  45. package/lib/validation/validators/yearMonth.ts +20 -0
  46. package/lib/validation/validators/yearMonthDate.ts +21 -0
  47. package/package.json +30 -29
  48. package/lib/assets/styles/variables/colors.css +0 -189
  49. package/lib/assets/styles/variables/easings.css +0 -12
  50. package/lib/assets/styles/variables/shadows.css +0 -7
  51. package/lib/assets/styles/variables/typography.css +0 -6
  52. package/lib/assets/styles/variables/z-indexes.css +0 -8
@@ -0,0 +1,244 @@
1
+ <template>
2
+ <SInputBase
3
+ class="SInputYMD"
4
+ :class="[size, mode, { disabled }]"
5
+ :name="name"
6
+ :label="label"
7
+ :note="note"
8
+ :help="help"
9
+ :error-message="errorMessage"
10
+ :validation="validation"
11
+ >
12
+ <div class="container">
13
+ <input
14
+ v-if="year"
15
+ class="input year"
16
+ type="number"
17
+ :value="value && value.year"
18
+ placeholder="YYYY"
19
+ :disabled="disabled"
20
+ @blur="updateYear"
21
+ >
22
+ <div
23
+ v-if="year && month"
24
+ class="separator"
25
+ />
26
+ <input
27
+ v-if="month"
28
+ class="input month"
29
+ type="number"
30
+ :value="value && value.month"
31
+ placeholder="M"
32
+ :disabled="disabled"
33
+ @blur="updateMonth"
34
+ >
35
+ <div
36
+ v-if="month && date"
37
+ class="separator"
38
+ />
39
+ <input
40
+ v-if="date"
41
+ class="input date"
42
+ type="number"
43
+ :value="value && value.date"
44
+ placeholder="D"
45
+ :disabled="disabled"
46
+ @blur="updateDate"
47
+ >
48
+ </div>
49
+
50
+ <template #before-help>
51
+ <slot name="before-help" />
52
+ </template>
53
+ </SInputBase>
54
+ </template>
55
+
56
+ <script lang="ts">
57
+ import { PropType, defineComponent } from '@vue/composition-api'
58
+ import { SyntheticInputEvent } from '../types/Utils'
59
+ import { Validation } from '../validation/Validation'
60
+ import SInputBase from './SInputBase.vue'
61
+
62
+ export type Size = 'mini'
63
+ export type Mode = 'outlined'
64
+
65
+ export interface Value {
66
+ year?: number
67
+ month?: number
68
+ date?: number
69
+ }
70
+
71
+ export type ValueType = 'year' | 'month' | 'date'
72
+
73
+ export interface Fields {
74
+ year?: boolean
75
+ month?: boolean
76
+ date?: boolean
77
+ }
78
+
79
+ export default defineComponent({
80
+ components: {
81
+ SInputBase
82
+ },
83
+
84
+ props: {
85
+ size: { type: String as PropType<Size>, default: 'mini' },
86
+ mode: { type: String as PropType<Mode>, default: 'outlined' },
87
+ name: { type: String, default: null },
88
+ label: { type: String, default: null },
89
+ note: { type: String, default: null },
90
+ help: { type: String, default: null },
91
+ placeholder: { type: String, default: null },
92
+ year: { type: Boolean, default: true },
93
+ month: { type: Boolean, default: true },
94
+ date: { type: Boolean, default: true },
95
+ disabled: { type: Boolean, default: false },
96
+ errorMessage: { type: Boolean, default: true },
97
+ value: { type: Object as PropType<Value>, default: null },
98
+ validation: { type: Object as PropType<Validation>, default: null }
99
+ },
100
+
101
+ setup(props, { emit }) {
102
+ const touched = {
103
+ year: false,
104
+ month: false,
105
+ date: false
106
+ }
107
+
108
+ function updateYear(e: SyntheticInputEvent): void {
109
+ const value = Number(e.target.value)
110
+ update('year', value === 0 ? undefined : value)
111
+ }
112
+
113
+ function updateMonth(e: SyntheticInputEvent): void {
114
+ const value = Number(e.target.value)
115
+ update('month', value === 0 ? undefined : value)
116
+ }
117
+
118
+ function updateDate(e: SyntheticInputEvent): void {
119
+ const value = Number(e.target.value)
120
+ update('date', value === 0 ? undefined : value)
121
+ }
122
+
123
+ function update(type: ValueType, value?: number): void {
124
+ const data = { ...props.value } as Value
125
+
126
+ setValue(data, type, value)
127
+
128
+ data.year === undefined && data.month === undefined && data.date === undefined
129
+ ? emit('input', null)
130
+ : emit('input', data)
131
+
132
+ emitTouch(type)
133
+ }
134
+
135
+ function setValue(data: Value, type: ValueType, value?: number): void {
136
+ if (value === undefined) {
137
+ delete data[type]
138
+ return
139
+ }
140
+
141
+ data[type] = value
142
+ }
143
+
144
+ function emitTouch(type: ValueType): void {
145
+ if (!props.validation || props.validation.$isDirty.value) {
146
+ return
147
+ }
148
+
149
+ touched[type] = true
150
+
151
+ if (createRequiredTouched().every(v => v)) {
152
+ props.validation.$touch()
153
+ }
154
+ }
155
+
156
+ function createRequiredTouched(): boolean[] {
157
+ const requiredTouched = [] as boolean[]
158
+
159
+ for (const key in touched) {
160
+ if ((props as any)[key]) {
161
+ requiredTouched.push((touched as any)[key])
162
+ }
163
+ }
164
+
165
+ return requiredTouched
166
+ }
167
+
168
+ return {
169
+ updateYear,
170
+ updateMonth,
171
+ updateDate
172
+ }
173
+ }
174
+ })
175
+ </script>
176
+
177
+ <style lang="postcss" scoped>
178
+ @import "@/assets/styles/variables";
179
+
180
+ .SInputYMD.mini {
181
+ .container {
182
+ padding: 0 4px;
183
+ }
184
+
185
+ .input {
186
+ padding: 3px 0;
187
+ text-align: center;
188
+ font-size: 14px;
189
+ }
190
+
191
+ .input.year { width: 48px; }
192
+ .input.month { width: 32px; }
193
+ .input.date { width: 32px; }
194
+
195
+ .separator {
196
+ padding: 3px 0;
197
+ line-height: 24px;
198
+ font-size: 14px;
199
+ }
200
+ }
201
+
202
+ .SInputYMD.outlined {
203
+ .container {
204
+ border: 1px solid var(--input-outlined-border);
205
+ border-radius: 4px;
206
+ transition: border-color .25s;
207
+
208
+ &:hover {
209
+ border-color: var(--input-focus-border);
210
+ }
211
+ }
212
+ }
213
+
214
+ .SInputYMD.outlined.disabled {
215
+ .container {
216
+ border-color: var(--input-outlined-border);
217
+ background-color: var(--input-outlined-bg-disabled);
218
+ }
219
+ }
220
+
221
+ .SInputYMD.disabled {
222
+ .container { cursor: not-allowed; }
223
+ .input { cursor: not-allowed; }
224
+ }
225
+
226
+ .SInputYMD.has-error {
227
+ .container {
228
+ border-color: var(--c-danger);
229
+ }
230
+ }
231
+
232
+ .container {
233
+ display: flex;
234
+ }
235
+
236
+ .input {
237
+ background-color: transparent;
238
+ }
239
+
240
+ .separator::before {
241
+ color: var(--c-text-3);
242
+ content: "/";
243
+ }
244
+ </style>
@@ -2,7 +2,12 @@
2
2
  <transition name="fade" :duration="250" appear>
3
3
  <div ref="el" class="SModal" @click="closeIfClosable">
4
4
  <transition name="fade">
5
- <div v-show="show" class="SModal-content" :style="contentStyles">
5
+ <div
6
+ v-show="show"
7
+ class="SModal-content"
8
+ :style="contentStyles"
9
+ @click="closeIfClosable"
10
+ >
6
11
  <component
7
12
  :is="resolvedComponent"
8
13
  :if="resolvedComponent"
@@ -58,7 +63,7 @@ export default defineComponent({
58
63
  }
59
64
 
60
65
  function isDescendant(el: Element): boolean {
61
- if (el.classList && el.classList.contains('SModal')) {
66
+ if (el.classList && el.classList.contains('SModal-content')) {
62
67
  return false
63
68
  }
64
69
 
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <article class="SSheet" :class="[size]">
3
+ <slot :close="close" />
4
+ </article>
5
+ </template>
6
+
7
+ <script lang="ts">
8
+ import { PropType, defineComponent } from '@vue/composition-api'
9
+ import { useStore } from '../composables/Store'
10
+
11
+ type Size = 'small' | 'medium' | 'large'
12
+
13
+ export default defineComponent({
14
+ props: {
15
+ size: { type: String as PropType<Size>, default: 'medium' }
16
+ },
17
+
18
+ setup() {
19
+ const store = useStore()
20
+
21
+ function close() {
22
+ store.dispatch('modal/close')
23
+ }
24
+
25
+ return {
26
+ close
27
+ }
28
+ }
29
+ })
30
+ </script>
31
+
32
+ <style lang="postcss" scoped>
33
+ @import "@/assets/styles/variables";
34
+
35
+ .SSheet {
36
+ margin: 0 auto;
37
+ border: 1px solid var(--c-divider-light);
38
+ border-radius: 8px;
39
+ background-color: var(--c-bg);
40
+ box-shadow: var(--shadow-depth-3);
41
+ overflow: hidden;
42
+ }
43
+
44
+ .SSheet.small { max-width: 392px; }
45
+ .SSheet.medium { max-width: 512px; }
46
+ .SSheet.large { max-width: 768px; }
47
+ </style>
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <footer class="SSheetFooter">
3
+ <slot />
4
+ </footer>
5
+ </template>
6
+
7
+ <style lang="postcss" scoped>
8
+ @import "@/assets/styles/variables";
9
+
10
+ .SSheetFooter {
11
+ border-top: 1px solid var(--c-divider-light);
12
+ padding: 0 16px;
13
+ }
14
+ </style>
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <div class="SSheetFooterAction">
3
+ <SButton
4
+ size="medium"
5
+ :type="type"
6
+ :mode="mode"
7
+ :label="label"
8
+ block
9
+ @click="$emit('click')"
10
+ />
11
+ </div>
12
+ </template>
13
+
14
+ <script lang="ts">
15
+ import { PropType, defineComponent } from '@nuxtjs/composition-api'
16
+ import SButton from './SButton.vue'
17
+
18
+ type Type = 'primary' | 'secondary' | 'tertiary' | 'text' | 'mute'
19
+ type Mode = 'neutral' | 'info' | 'success' | 'warning' | 'danger'
20
+
21
+ export default defineComponent({
22
+ components: {
23
+ SButton
24
+ },
25
+
26
+ props: {
27
+ type: { type: String as PropType<Type>, default: 'primary' },
28
+ mode: { type: String as PropType<Mode>, default: 'neutral' },
29
+ label: { type: String, default: null }
30
+ }
31
+ })
32
+ </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="SSheetFooterActions">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <style lang="postcss" scoped>
8
+ @import "@/assets/styles/variables";
9
+
10
+ .SSheetFooterActions {
11
+ display: flex;
12
+ justify-content: flex-end;
13
+ padding: 12px 0 11px;
14
+ }
15
+
16
+ .SSheetFooterActions >>> .SSheetFooterAction + .SSheetFooterAction {
17
+ padding-left: 8px;
18
+ }
19
+ </style>
@@ -0,0 +1,75 @@
1
+ <template>
2
+ <header class="SSheetHeader">
3
+ <slot />
4
+
5
+ <div v-if="closable" class="close">
6
+ <button class="close-button" @click="close">
7
+ <SIconX class="close-icon" />
8
+ </button>
9
+ </div>
10
+ </header>
11
+ </template>
12
+
13
+ <script lang="ts">
14
+ import { defineComponent } from '@vue/composition-api'
15
+ import { useStore } from '../composables/Store'
16
+ import SIconX from './icons/SIconX.vue'
17
+
18
+ export default defineComponent({
19
+ components: {
20
+ SIconX
21
+ },
22
+
23
+ props: {
24
+ closable: { type: Boolean, default: true }
25
+ },
26
+
27
+ setup() {
28
+ const store = useStore()
29
+
30
+ function close() {
31
+ store.dispatch('modal/close')
32
+ }
33
+
34
+ return {
35
+ close
36
+ }
37
+ }
38
+ })
39
+ </script>
40
+
41
+ <style lang="postcss" scoped>
42
+ @import "@/assets/styles/variables";
43
+
44
+ .SSheetHeader {
45
+ display: flex;
46
+ justify-content: space-between;
47
+ border-bottom: 1px solid var(--c-divider-light);
48
+ min-height: 48px;
49
+ background-color: var(--c-bg-soft);
50
+ }
51
+
52
+ .close {
53
+ margin: 0 0 0 auto;
54
+ }
55
+
56
+ .close-button {
57
+ display: flex;
58
+ justify-content: center;
59
+ align-items: center;
60
+ width: 48px;
61
+ height: 47px;
62
+ color: var(--c-text-3);
63
+ transition: color .25s;
64
+
65
+ &:hover {
66
+ color: var(--c-text-1);
67
+ }
68
+ }
69
+
70
+ .close-icon {
71
+ width: 20px;
72
+ height: 20px;
73
+ fill: currentColor;
74
+ }
75
+ </style>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <h1 class="SSheetHeaderTitle">
3
+ <slot />
4
+ </h1>
5
+ </template>
6
+
7
+ <style lang="postcss" scoped>
8
+ @import "@/assets/styles/variables";
9
+
10
+ .SSheetHeaderTitle {
11
+ margin: 0;
12
+ padding: 14px 16px 10px;
13
+ line-height: 20px;
14
+ font-size: 16px;
15
+ font-weight: 500;
16
+ }
17
+ </style>
@@ -0,0 +1,92 @@
1
+ <template>
2
+ <div class="SSheetMedium">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <style lang="postcss" scoped>
8
+ @import "@/assets/styles/variables";
9
+
10
+ .SSheetMedium {
11
+ padding: 24px 16px;
12
+
13
+ @media (min-width: 768px) {
14
+ padding: 24px;
15
+ }
16
+ }
17
+
18
+ .SSheet.small .SSheetMedium {
19
+ @media (min-width: 768px) {
20
+ padding: 24px 16px;
21
+ }
22
+ }
23
+
24
+ .SSheetMedium >>> h1 {
25
+ line-height: 32px;
26
+ font-size: 20px;
27
+ font-weight: 500;
28
+ }
29
+
30
+ .SSheetMedium >>> h1 + p {
31
+ margin-top: 8px;
32
+ }
33
+
34
+ .SSheetMedium >>> p {
35
+ margin: 16px 0;
36
+ line-height: 24px;
37
+ font-size: 14px;
38
+ font-weight: 400;
39
+ }
40
+
41
+ .SSheetMedium >>> p:first-child {
42
+ margin-top: 0;
43
+ }
44
+
45
+ .SSheetMedium >>> p:last-child {
46
+ margin-bottom: 0;
47
+ }
48
+
49
+ .SSheetMedium >>> a {
50
+ font-weight: 500;
51
+ color: var(--c-info);
52
+ transition: color .25s;
53
+
54
+ &:hover {
55
+ color: var(--c-info-dark);
56
+ }
57
+ }
58
+
59
+ .SSheetMedium >>> ul {
60
+ margin: 16px 0;
61
+ }
62
+
63
+ .SSheetMedium >>> ul:last-child {
64
+ margin-bottom: 0;
65
+ }
66
+
67
+ .SSheetMedium >>> li {
68
+ position: relative;
69
+ padding-left: 20px;
70
+ font-size: 14px;
71
+ font-weight: 400;
72
+ }
73
+
74
+ .SSheetMedium >>> li::before {
75
+ position: absolute;
76
+ top: 9px;
77
+ left: 4px;
78
+ border-radius: 50%;
79
+ width: 6px;
80
+ height: 6px;
81
+ background-color: var(--c-text-3);
82
+ content: "";
83
+ }
84
+
85
+ .SSheetMedium >>> li + li {
86
+ margin-top: 4px;
87
+ }
88
+
89
+ .SSheetMedium >>> li > ul {
90
+ margin: 4px 0 0;
91
+ }
92
+ </style>
@@ -57,6 +57,7 @@ export default defineComponent({
57
57
 
58
58
  .SSnackbar {
59
59
  position: relative;
60
+ border: 1px solid transparent;
60
61
  border-radius: 4px;
61
62
  width: 100%;
62
63
  color: var(--c-text-dark-1);
@@ -64,6 +65,10 @@ export default defineComponent({
64
65
  box-shadow: var(--shadow-depth-5);
65
66
  }
66
67
 
68
+ .dark-mode .SSnackbar {
69
+ border-color: var(--c-divider-light);
70
+ }
71
+
67
72
  .close {
68
73
  position: absolute;
69
74
  top: 4px;
@@ -83,8 +88,8 @@ export default defineComponent({
83
88
  }
84
89
 
85
90
  .close-icon {
86
- width: 12px;
87
- height: 12px;
91
+ width: 16px;
92
+ height: 16px;
88
93
  fill: var(--c-text-dark-2);
89
94
  transition: fill .25s;
90
95
  }
Binary file
@@ -0,0 +1,10 @@
1
+ <template>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
3
+ <circle cx="8.83" cy="12" r="2" />
4
+ <circle cx="8.83" cy="5" r="2" />
5
+ <circle cx="8.83" cy="19" r="2" />
6
+ <circle cx="15.17" cy="12" r="2" />
7
+ <circle cx="15.17" cy="5" r="2" />
8
+ <circle cx="15.17" cy="19" r="2" />
9
+ </svg>
10
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
3
+ <path d="M22.9,11.6C22.9,11.6,22.9,11.6,22.9,11.6l-3.5-6.9c-0.5-1-1.5-1.7-2.7-1.7H7.2C6.1,3,5.1,3.6,4.6,4.7l-3.4,6.9c0,0,0,0,0,0C1,11.7,1,11.8,1,12v6c0,1.7,1.3,3,3,3h16c1.7,0,3-1.3,3-3v-6C23,11.8,23,11.7,22.9,11.6z M6.3,5.6C6.3,5.6,6.3,5.6,6.3,5.6C6.5,5.2,6.9,5,7.2,5h9.5c0.4,0,0.7,0.2,0.9,0.6l2.7,5.4H16c-0.3,0-0.6,0.2-0.8,0.4L13.5,14h-2.9l-1.7-2.6C8.6,11.2,8.3,11,8,11H3.6L6.3,5.6z M20,19H4c-0.6,0-1-0.4-1-1v-5h4.5l1.7,2.6C9.4,15.8,9.7,16,10,16h4c0.3,0,0.6-0.2,0.8-0.4l1.7-2.6H21v5C21,18.6,20.6,19,20,19z" />
4
+ </svg>
5
+ </template>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
3
+ <path d="M19.64,9.82H18.55V6.55a6.55,6.55,0,0,0-13.1,0V9.82H4.36a3.28,3.28,0,0,0-3.27,3.27v7.64A3.28,3.28,0,0,0,4.36,24H19.64a3.28,3.28,0,0,0,3.27-3.27V13.09A3.28,3.28,0,0,0,19.64,9.82Zm-12-3.27a4.36,4.36,0,1,1,8.72,0V9.82H7.64ZM20.73,20.73a1.09,1.09,0,0,1-1.09,1.09H4.36a1.09,1.09,0,0,1-1.09-1.09V13.09A1.09,1.09,0,0,1,4.36,12H19.64a1.09,1.09,0,0,1,1.09,1.09Z" />
4
+ </svg>
5
+ </template>
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
3
+ <circle cx="12" cy="12" r="2" />
4
+ <circle cx="12" cy="5" r="2" />
5
+ <circle cx="12" cy="19" r="2" />
6
+ </svg>
7
+ </template>