@globalbrain/sefirot 0.72.0 → 2.0.0-draft.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 (175) hide show
  1. package/CHANGELOG.md +8 -808
  2. package/README.md +1 -1
  3. package/lib/assets/styles/bootstrap.css +1 -2
  4. package/lib/assets/styles/variables.css +14 -47
  5. package/lib/components/SAvatar.vue +9 -18
  6. package/lib/components/SButton.vue +35 -48
  7. package/lib/components/SDialog.vue +16 -34
  8. package/lib/components/SDropdown.vue +36 -55
  9. package/lib/components/SDropdownItem.vue +27 -39
  10. package/lib/components/SDropdownItemText.vue +4 -9
  11. package/lib/components/SDropdownItemUser.vue +4 -12
  12. package/lib/components/SInputBase.vue +33 -45
  13. package/lib/components/SInputCheckbox.vue +17 -37
  14. package/lib/components/SInputDropdown.vue +109 -171
  15. package/lib/components/SInputDropdownItem.vue +26 -32
  16. package/lib/components/SInputDropdownItemText.vue +6 -11
  17. package/lib/components/SInputDropdownItemTextTag.vue +10 -17
  18. package/lib/components/SInputDropdownItemUser.vue +5 -13
  19. package/lib/components/SInputDropdownItemUserTag.vue +9 -16
  20. package/lib/components/SInputFile.vue +38 -53
  21. package/lib/components/SInputHMS.vue +91 -114
  22. package/lib/components/SInputNumber.vue +27 -106
  23. package/lib/components/SInputRadio.vue +21 -34
  24. package/lib/components/SInputRadios.vue +36 -46
  25. package/lib/components/SInputText.vue +72 -628
  26. package/lib/components/SInputTextarea.vue +54 -113
  27. package/lib/components/SInputYMD.vue +94 -105
  28. package/lib/components/SLink.vue +16 -52
  29. package/lib/components/SModal.vue +39 -98
  30. package/lib/components/SPortalModals.vue +37 -54
  31. package/lib/components/SPortalSnackbars.vue +9 -24
  32. package/lib/components/SSheet.vue +73 -28
  33. package/lib/components/SSheetFooter.vue +5 -3
  34. package/lib/components/SSheetFooterAction.vue +10 -15
  35. package/lib/components/SSheetFooterActions.vue +2 -4
  36. package/lib/components/SSheetMedium.vue +14 -22
  37. package/lib/components/SSheetTitle.vue +20 -0
  38. package/lib/components/SSnackbar.vue +18 -28
  39. package/lib/composables/Dialog.ts +9 -17
  40. package/lib/composables/Dropdown.ts +2 -2
  41. package/lib/composables/{Menu.ts → Flyout.ts} +11 -4
  42. package/lib/composables/Form.ts +42 -44
  43. package/lib/composables/Modal.ts +11 -19
  44. package/lib/composables/Snackbar.ts +18 -0
  45. package/lib/composables/Validation.ts +28 -0
  46. package/lib/mixins/Sheet.ts +5 -7
  47. package/lib/store/Sefirot.ts +8 -13
  48. package/lib/store/dialog/index.ts +20 -10
  49. package/lib/store/modal/index.ts +11 -18
  50. package/lib/store/snackbars/index.ts +3 -4
  51. package/lib/support/{Util.ts → Utils.ts} +0 -2
  52. package/lib/types/Utils.ts +0 -7
  53. package/lib/types/vue-shims.d.ts +7 -0
  54. package/lib/validation/rules/checked.ts +6 -10
  55. package/lib/validation/rules/fileExtension.ts +9 -9
  56. package/lib/validation/rules/hms.ts +9 -9
  57. package/lib/validation/rules/index.ts +10 -74
  58. package/lib/validation/rules/maxLength.ts +10 -9
  59. package/lib/validation/rules/minLength.ts +12 -0
  60. package/lib/validation/rules/required.ts +2 -10
  61. package/lib/validation/rules/requiredHms.ts +11 -0
  62. package/lib/validation/rules/requiredIf.ts +3 -11
  63. package/lib/validation/rules/requiredYmd.ts +11 -0
  64. package/lib/validation/rules/ymd.ts +11 -0
  65. package/lib/validation/validators/checked.ts +1 -1
  66. package/lib/validation/validators/fileExtension.ts +1 -1
  67. package/lib/validation/validators/hms.ts +5 -5
  68. package/lib/validation/validators/requiredHms.ts +17 -0
  69. package/lib/validation/validators/requiredYmd.ts +7 -0
  70. package/lib/validation/validators/ymd.ts +41 -0
  71. package/package.json +45 -50
  72. package/lib/components/SAction.vue +0 -37
  73. package/lib/components/SActionAvatar.vue +0 -25
  74. package/lib/components/SActionButton.vue +0 -40
  75. package/lib/components/SActionPill.vue +0 -35
  76. package/lib/components/SActionSwitch.vue +0 -37
  77. package/lib/components/SAlert.vue +0 -145
  78. package/lib/components/SButtonGroup.vue +0 -160
  79. package/lib/components/SCard.vue +0 -111
  80. package/lib/components/SCardFooter.vue +0 -74
  81. package/lib/components/SCardHeader.vue +0 -213
  82. package/lib/components/SGrid.vue +0 -237
  83. package/lib/components/SGridActionLink.vue +0 -53
  84. package/lib/components/SGridActionMulti.vue +0 -139
  85. package/lib/components/SGridActionSingle.vue +0 -64
  86. package/lib/components/SHeader.vue +0 -180
  87. package/lib/components/SInputCheckboxes.vue +0 -87
  88. package/lib/components/SInputDate.vue +0 -192
  89. package/lib/components/SInputDay.vue +0 -87
  90. package/lib/components/SInputMonth.vue +0 -86
  91. package/lib/components/SInputSelect.vue +0 -298
  92. package/lib/components/SInputSwitch.vue +0 -212
  93. package/lib/components/SInputSwitches.vue +0 -108
  94. package/lib/components/SInputTime.vue +0 -255
  95. package/lib/components/SInputYear.vue +0 -60
  96. package/lib/components/SMarkdown.vue +0 -56
  97. package/lib/components/SPlaceholderBlank.vue +0 -113
  98. package/lib/components/SPlaceholderImage.vue +0 -83
  99. package/lib/components/SPortalScreens.vue +0 -62
  100. package/lib/components/SProgressBar.vue +0 -89
  101. package/lib/components/SResponsive.vue +0 -46
  102. package/lib/components/SScreen.vue +0 -81
  103. package/lib/components/SSheetHeader.vue +0 -75
  104. package/lib/components/SSheetHeaderTitle.vue +0 -17
  105. package/lib/components/SStep.vue +0 -107
  106. package/lib/components/SSteps.vue +0 -75
  107. package/lib/components/STag.vue +0 -67
  108. package/lib/components/STooltip.vue +0 -134
  109. package/lib/components/SWindow.vue +0 -158
  110. package/lib/components/icons/SIconCopy.vue +0 -6
  111. package/lib/composables/Action.ts +0 -141
  112. package/lib/composables/Alert.ts +0 -50
  113. package/lib/composables/Card.ts +0 -46
  114. package/lib/composables/FormValidation.ts +0 -150
  115. package/lib/composables/Header.ts +0 -72
  116. package/lib/composables/InputDropdown.ts +0 -6
  117. package/lib/composables/Markdown.ts +0 -138
  118. package/lib/composables/Router.ts +0 -20
  119. package/lib/composables/Step.ts +0 -7
  120. package/lib/composables/Store.ts +0 -9
  121. package/lib/composables/Tag.ts +0 -32
  122. package/lib/composables/Tooltip.ts +0 -91
  123. package/lib/composables/Utils.ts +0 -115
  124. package/lib/composables/markdown/LinkPlugin.ts +0 -45
  125. package/lib/compositions/useForm.ts +0 -17
  126. package/lib/compositions/useResizeObserver.ts +0 -25
  127. package/lib/compositions/useTime.ts +0 -26
  128. package/lib/store/alert/index.ts +0 -32
  129. package/lib/store/screen/index.ts +0 -46
  130. package/lib/types/v-calendar.d.ts +0 -5
  131. package/lib/validation/Validation.ts +0 -151
  132. package/lib/validation/rules/day.ts +0 -11
  133. package/lib/validation/rules/email.ts +0 -11
  134. package/lib/validation/rules/every.ts +0 -38
  135. package/lib/validation/rules/include.ts +0 -11
  136. package/lib/validation/rules/includeSome.ts +0 -11
  137. package/lib/validation/rules/integer.ts +0 -11
  138. package/lib/validation/rules/maxValue.ts +0 -11
  139. package/lib/validation/rules/minValue.ts +0 -11
  140. package/lib/validation/rules/month.ts +0 -11
  141. package/lib/validation/rules/not.ts +0 -10
  142. package/lib/validation/rules/regex.ts +0 -11
  143. package/lib/validation/rules/requiredHMS.ts +0 -11
  144. package/lib/validation/rules/requiredMonthDate.ts +0 -11
  145. package/lib/validation/rules/requiredYearMonth.ts +0 -11
  146. package/lib/validation/rules/requiredYearMonthDate.ts +0 -11
  147. package/lib/validation/rules/rule.ts +0 -5
  148. package/lib/validation/rules/sameAs.ts +0 -11
  149. package/lib/validation/rules/url.ts +0 -11
  150. package/lib/validation/rules/validateIf.ts +0 -27
  151. package/lib/validation/rules/year.ts +0 -11
  152. package/lib/validation/rules/yearMonth.ts +0 -11
  153. package/lib/validation/rules/yearMonthDate.ts +0 -11
  154. package/lib/validation/validators/day.ts +0 -29
  155. package/lib/validation/validators/email.ts +0 -5
  156. package/lib/validation/validators/include.ts +0 -5
  157. package/lib/validation/validators/includeSome.ts +0 -5
  158. package/lib/validation/validators/index.ts +0 -51
  159. package/lib/validation/validators/integer.ts +0 -6
  160. package/lib/validation/validators/maxLength.ts +0 -3
  161. package/lib/validation/validators/maxValue.ts +0 -3
  162. package/lib/validation/validators/minValue.ts +0 -3
  163. package/lib/validation/validators/month.ts +0 -3
  164. package/lib/validation/validators/monthDate.ts +0 -20
  165. package/lib/validation/validators/regex.ts +0 -3
  166. package/lib/validation/validators/required.ts +0 -27
  167. package/lib/validation/validators/requiredHMS.ts +0 -17
  168. package/lib/validation/validators/requiredMonthDate.ts +0 -8
  169. package/lib/validation/validators/requiredYearMonth.ts +0 -8
  170. package/lib/validation/validators/requiredYearMonthDate.ts +0 -9
  171. package/lib/validation/validators/sameAs.ts +0 -5
  172. package/lib/validation/validators/url.ts +0 -5
  173. package/lib/validation/validators/year.ts +0 -3
  174. package/lib/validation/validators/yearMonth.ts +0 -20
  175. package/lib/validation/validators/yearMonthDate.ts +0 -21
@@ -1,145 +0,0 @@
1
- <template>
2
- <div class="SAlert" :class="[type]">
3
- <SCard :collapsable="false" :depth="3">
4
- <div class="container">
5
- <div class="icon">
6
- <component :is="icon" class="icon-svg" />
7
- </div>
8
-
9
- <div class="content">
10
- <p class="title">{{ title }}</p>
11
- <p class="text">{{ text }}</p>
12
-
13
- <div class="actions">
14
- <div v-for="(action, index) in actions" :key="index" class="action">
15
- <SButton
16
- size="small"
17
- :type="action.type"
18
- :mode="action.mode"
19
- :icon="action.icon"
20
- :label="action.label"
21
- @click="action.callback"
22
- />
23
- </div>
24
- </div>
25
- </div>
26
- </div>
27
- </SCard>
28
- </div>
29
- </template>
30
-
31
- <script lang="ts">
32
- import { PropType, defineComponent, computed } from '@vue/composition-api'
33
- import { Action, AlertMode, AlertModes } from '../composables/Alert'
34
- import SIconInfo from './icons/SIconInfo.vue'
35
- import SIconCheckCircle from './icons/SIconCheckCircle.vue'
36
- import SIconWarning from './icons/SIconWarning.vue'
37
- import SIconXCircle from './icons/SIconXCircle.vue'
38
- import SButton from './SButton.vue'
39
- import SCard from './SCard.vue'
40
-
41
- export default defineComponent({
42
- components: {
43
- SButton,
44
- SCard
45
- },
46
-
47
- props: {
48
- type: { type: String as PropType<AlertMode>, default: AlertModes.Info },
49
- title: { type: String, default: null },
50
- text: { type: String, default: null },
51
- actions: { type: Array as PropType<Action[]>, default: () => [] }
52
- },
53
-
54
- setup(props) {
55
- const icon = computed(() => {
56
- switch (props.type) {
57
- case AlertModes.Info:
58
- return SIconInfo
59
- case AlertModes.Success:
60
- return SIconCheckCircle
61
- case AlertModes.Warning:
62
- return SIconWarning
63
- case AlertModes.Danger:
64
- return SIconXCircle
65
- }
66
- })
67
-
68
- return {
69
- icon
70
- }
71
- }
72
- })
73
- </script>
74
-
75
- <style lang="postcss" scoped>
76
- @import "@/assets/styles/variables";
77
-
78
- .SAlert {
79
- margin: 64px 16px;
80
- border-radius: 8px;
81
- max-width: 512px;
82
-
83
- @media (min-width: 544px) {
84
- margin: 64px auto;
85
- }
86
- }
87
-
88
- .SAlert.info .icon-svg { fill: var(--c-info); }
89
- .SAlert.success .icon-svg { fill: var(--c-success); }
90
- .SAlert.warning .icon-svg { fill: var(--c-warning); }
91
- .SAlert.danger .icon-svg { fill: var(--c-danger); }
92
-
93
- .container {
94
- @media (min-width: 544px) {
95
- display: flex;
96
- }
97
- }
98
-
99
- .icon {
100
- padding: 16px 16px 8px;
101
-
102
- @media (min-width: 544px) {
103
- display: flex;
104
- justify-content: center;
105
- align-items: center;
106
- flex-shrink: 0;
107
- padding: 0;
108
- width: 64px;
109
- height: 64px;
110
- }
111
- }
112
-
113
- .icon-svg {
114
- width: 24px;
115
- height: 24px;
116
- }
117
-
118
- .content {
119
- padding: 0 16px 16px;
120
-
121
- @media (min-width: 544px) {
122
- flex-grow: 1;
123
- padding: 20px 24px 20px 0;
124
- }
125
- }
126
-
127
- .title {
128
- font-size: 16px;
129
- font-weight: 500;
130
- }
131
-
132
- .text {
133
- font-size: 14px;
134
- }
135
-
136
- .actions {
137
- display: flex;
138
- justify-content: flex-end;
139
- padding-top: 16px;
140
- }
141
-
142
- .action + .action {
143
- padding-left: 8px;
144
- }
145
- </style>
@@ -1,160 +0,0 @@
1
- <template>
2
- <div class="SButtonGroup" :class="classes">
3
- <button
4
- v-for="item in items"
5
- :key="item.value"
6
- class="button"
7
- :class="getButtonClasses(item)"
8
- @click="handleClick(item.value)"
9
- >
10
- <span class="content">
11
- {{ item.label }}
12
- </span>
13
- </button>
14
- </div>
15
- </template>
16
-
17
- <script lang="ts">
18
- import { PropType, defineComponent, computed } from '@vue/composition-api'
19
-
20
- interface ButtonGroupItem {
21
- label: string
22
- value: string
23
- mode: Mode
24
- }
25
-
26
- type Mode = 'neutral' | 'info' | 'success' | 'warning' | 'danger'
27
- type Size = 'mini' | 'small' | 'medium' | 'large' | 'jumbo'
28
-
29
- export default defineComponent({
30
- model: {
31
- prop: 'value',
32
- event: 'change'
33
- },
34
-
35
- props: {
36
- items: { type: Array as PropType<ButtonGroupItem[]>, required: true },
37
- size: { type: String as PropType<Size>, default: 'medium' },
38
- value: { type: String, default: null }
39
- },
40
-
41
- setup(props, { emit }) {
42
- const classes = computed(() => [props.size])
43
-
44
- function getButtonClasses(button: ButtonGroupItem) {
45
- return [
46
- { active: button.value === props.value },
47
- button.mode ?? 'neutral'
48
- ]
49
- }
50
-
51
- function handleClick(value: string) {
52
- emit('change', value)
53
- }
54
-
55
- return {
56
- classes,
57
- getButtonClasses,
58
- handleClick
59
- }
60
- }
61
- })
62
- </script>
63
-
64
- <style lang="postcss" scoped>
65
- .SButtonGroup {
66
- display: flex;
67
- border: 1px solid var(--c-divider);
68
- border-radius: 4px;
69
- overflow: hidden;
70
- }
71
-
72
- .SButtonGroup.mini {
73
- height: 28px;
74
-
75
- .button {
76
- padding: 0 8px;
77
- height: 28px;
78
- font-size: 12px;
79
- font-weight: 500;
80
- }
81
- }
82
-
83
- .SButtonGroup.small {
84
- height: 32px;
85
-
86
- .button {
87
- padding: 0 10px;
88
- height: 32px;
89
- font-size: 12px;
90
- font-weight: 500;
91
- }
92
- }
93
-
94
- .SButtonGroup.medium {
95
- height: 40px;
96
-
97
- .button {
98
- padding: 0 12px;
99
- height: 40px;
100
- font-size: 13px;
101
- font-weight: 500;
102
- }
103
- }
104
-
105
- .SButtonGroup.large {
106
- height: 48px;
107
-
108
- .button {
109
- padding: 0 14px;
110
- height: 48px;
111
- font-size: 14px;
112
- font-weight: 500;
113
- }
114
- }
115
-
116
- .SButtonGroup.jumbo {
117
- height: 64px;
118
-
119
- .button {
120
- padding: 0 24px;
121
- height: 64px;
122
- font-size: 14px;
123
- font-weight: 500;
124
- }
125
- }
126
-
127
- .button {
128
- border-left: 1px solid transparent;
129
- letter-spacing: .4px;
130
- color: var(--c-text-2);
131
- white-space: nowrap;
132
- transition: color .25s, background-color .25s;
133
-
134
- &:hover {
135
- color: var(--c-text-1);
136
- }
137
- }
138
-
139
- .button:not(:first-child) {
140
- border-left: 1px solid var(--c-divider);
141
- }
142
-
143
- .button.active {
144
- color: var(--c-text-dark-1);
145
- }
146
-
147
- .button.neutral.active { background-color: var(--c-black); }
148
- .button.info.active { background-color: var(--c-info); }
149
- .button.success.active { background-color: var(--c-success); }
150
- .button.warning.active { background-color: var(--c-warning); }
151
- .button.danger.active { background-color: var(--c-danger); }
152
-
153
- .content {
154
- display: flex;
155
- justify-content: center;
156
- align-items: center;
157
- width: 100%;
158
- height: 100%;
159
- }
160
- </style>
@@ -1,111 +0,0 @@
1
- <template>
2
- <div class="SCard" :class="classes">
3
- <div v-if="header" class="header">
4
- <SCardHeader
5
- :is-collapsed="isCollapsed"
6
- :title="header.title"
7
- :actions="header.actions"
8
- :mode="header.mode"
9
- :collapsable="collapsable"
10
- @collapse="toggleCollapse"
11
- />
12
- </div>
13
-
14
- <div class="content">
15
- <slot />
16
- </div>
17
-
18
- <div v-if="showFooter" class="footer">
19
- <SCardFooter :actions="footer.actions" />
20
- </div>
21
- </div>
22
- </template>
23
-
24
- <script lang="ts">
25
- import { PropType, defineComponent, ref, computed } from '@vue/composition-api'
26
- import { Header, Footer, Mode } from '../composables/Card'
27
- import { get } from '../composables/Utils'
28
- import SCardHeader from './SCardHeader.vue'
29
- import SCardFooter from './SCardFooter.vue'
30
-
31
- export default defineComponent({
32
- components: {
33
- SCardHeader,
34
- SCardFooter
35
- },
36
-
37
- props: {
38
- header: { type: Object as PropType<Header>, default: null },
39
- footer: { type: Object as PropType<Footer>, default: null },
40
- mode: { type: String as PropType<Mode>, default: 'neutral' },
41
- round: { type: Number, default: 8 },
42
- depth: { type: Number, default: 0 },
43
- collapsable: { type: Boolean, default: true }
44
- },
45
-
46
- setup(props) {
47
- const isCollapsed = ref(false)
48
- const showFooter = computed(() => {
49
- const actions = get(props.footer?.actions) ?? []
50
-
51
- return actions.length > 0
52
- })
53
-
54
- const classes = computed(() => [
55
- { collapsed: isCollapsed.value },
56
- props.mode,
57
- `round-${props.round}`,
58
- `depth-${props.depth}`
59
- ])
60
-
61
- function toggleCollapse(): void {
62
- isCollapsed.value = !isCollapsed.value
63
- }
64
-
65
- return {
66
- isCollapsed,
67
- showFooter,
68
- classes,
69
- toggleCollapse
70
- }
71
- }
72
- })
73
- </script>
74
-
75
- <style lang="postcss" scoped>
76
- @import "@/assets/styles/variables";
77
-
78
- .SCard {
79
- border: 1px solid transparent;
80
- background-color: var(--card-bg);
81
- }
82
-
83
- .SCard.neutral { border-color: var(--c-divider-light); }
84
- .SCard.info { border-color: var(--c-info); }
85
- .SCard.success { border-color: var(--c-success); }
86
- .SCard.warning { border-color: var(--c-warning); }
87
- .SCard.danger { border-color: var(--c-danger); }
88
-
89
- .SCard.collapsed {
90
- height: 48px;
91
- overflow: hidden;
92
- }
93
-
94
- .SCard.round-4 { border-radius: 4px; }
95
- .SCard.round-8 { border-radius: 8px; }
96
-
97
- .SCard.depth-0 { box-shadow: none; }
98
- .SCard.depth-1 { box-shadow: var(--card-shadow-depth-1); }
99
- .SCard.depth-2 { box-shadow: var(--card-shadow-depth-2); }
100
- .SCard.depth-3 { box-shadow: var(--card-shadow-depth-3); }
101
- .SCard.depth-4 { box-shadow: var(--card-shadow-depth-4); }
102
- .SCard.depth-5 { box-shadow: var(--card-shadow-depth-5); }
103
-
104
- .content {
105
- position: relative;
106
- }
107
-
108
- .footer {
109
- overflow: hidden;
110
- }
111
- </style>
@@ -1,74 +0,0 @@
1
- <template>
2
- <div class="SCardFooter" :class="classes">
3
- <div v-if="unwrappedActions.length > 0" class="actions">
4
- <div v-for="(action, index) in unwrappedActions" :key="index" class="action">
5
- <SButton
6
- size="small"
7
- :type="action.type"
8
- :mode="action.mode"
9
- :icon="action.icon"
10
- :label="action.label"
11
- block
12
- @click="action.callback ? action.callback() : () => {}"
13
- />
14
- </div>
15
- </div>
16
- </div>
17
- </template>
18
-
19
- <script lang="ts">
20
- import { defineComponent, PropType, computed } from '@vue/composition-api'
21
- import { Refish, get } from '../composables/Utils'
22
- import { Action } from '../composables/Card'
23
- import SButton from './SButton.vue'
24
-
25
- export default defineComponent({
26
- components: {
27
- SButton
28
- },
29
-
30
- props: {
31
- actions: { type: [Object, Array] as PropType<Refish<Action[]>>, required: true },
32
- round: { type: Number, default: 8 }
33
- },
34
-
35
- setup(props) {
36
- const classes = computed(() => [
37
- `round-${props.round}`
38
- ])
39
-
40
- const unwrappedActions = computed(() => get(props.actions))
41
-
42
- return {
43
- classes,
44
- unwrappedActions
45
- }
46
- }
47
- })
48
- </script>
49
-
50
- <style lang="postcss" scoped>
51
- @import "@/assets/styles/variables";
52
-
53
- .SCardFooter {
54
- border-top: 1px solid var(--c-divider-light);
55
- padding: 16px 16px 15px;
56
- background-color: var(--card-bg);
57
- }
58
-
59
- .SCardFooter.round-4 { border-radius: 0 0 4px 4px; }
60
- .SCardFooter.round-8 { border-radius: 0 0 8px 8px; }
61
-
62
- .actions {
63
- display: flex;
64
- justify-content: flex-end;
65
- }
66
-
67
- .action {
68
- min-width: 96px;
69
- }
70
-
71
- .action + .action {
72
- margin-left: 8px;
73
- }
74
- </style>
@@ -1,213 +0,0 @@
1
- <template>
2
- <div class="SCardHeader" :class="classes">
3
- <div class="title">
4
- <p v-if="title" class="title-text">{{ title }}</p>
5
- </div>
6
-
7
- <div class="actions">
8
- <template v-if="unwrapedActions.length > 0">
9
- <template v-for="(action, index) in unwrapedActions">
10
- <SToolTip :key="index" :text="action.disabled">
11
- <component
12
- :is="action.link ? 'a' : 'button'"
13
- class="action"
14
- :class="[action.mode || 'neutral', { disabled: action.disabled }]"
15
- :href="action.link ? action.link : null"
16
- @click.prevent="handleCallback(action)"
17
- >
18
- <component :is="getIcon(action.icon, !!action.disabled)" class="action-icon" />
19
- </component>
20
- </SToolTip>
21
- </template>
22
- </template>
23
-
24
- <div v-if="collapsable" class="action action-collapse">
25
- <button class="collapse" @click="$emit('collapse')">
26
- <SIconChevronDown class="collapse-icon" />
27
- </button>
28
- </div>
29
- </div>
30
- </div>
31
- </template>
32
-
33
- <script lang="ts">
34
- import { PropType, defineComponent, computed } from '@vue/composition-api'
35
- import { useRouter } from '../composables/Router'
36
- import { Refish, get } from '../composables/Utils'
37
- import { Action, ActionIconType, Mode } from '../composables/Card'
38
- import SIconPlus from './icons/SIconPlus.vue'
39
- import SIconPlusOff from './icons/SIconPlusOff.vue'
40
- import SIconEdit3 from './icons/SIconEdit3.vue'
41
- import SIconEdit3Off from './icons/SIconEdit3Off.vue'
42
- import SIconTrash2 from './icons/SIconTrash2.vue'
43
- import SIconTrash2Off from './icons/SIconTrash2Off.vue'
44
- import SIconChevronDown from './icons/SIconChevronDown.vue'
45
- import SToolTip from './STooltip.vue'
46
-
47
- export default defineComponent({
48
- components: {
49
- SIconChevronDown,
50
- SToolTip
51
- },
52
-
53
- props: {
54
- isCollapsed: { type: Boolean, required: true },
55
- title: { type: String, default: null },
56
- actions: { type: [Array, Object] as PropType<Refish<Action[]>>, default: () => [] },
57
- mode: { type: String as PropType<Mode>, default: 'neutral' },
58
- round: { type: Number, default: 8 },
59
- collapsable: { type: Boolean, required: true }
60
- },
61
-
62
- setup(props) {
63
- const router = useRouter()
64
-
65
- const classes = computed(() => [
66
- { collapsed: props.isCollapsed },
67
- props.mode,
68
- `round-${props.round}`
69
- ])
70
-
71
- const unwrapedActions = computed(() => get(props.actions))
72
-
73
- function getIcon(icon: ActionIconType | object, disabled: boolean) {
74
- if (typeof icon === 'object') {
75
- return icon
76
- }
77
-
78
- if (icon === 'plus') {
79
- return disabled ? SIconPlusOff : SIconPlus
80
- }
81
-
82
- if (icon === 'edit-3') {
83
- return disabled ? SIconEdit3Off : SIconEdit3
84
- }
85
-
86
- if (icon === 'trash-2') {
87
- return disabled ? SIconTrash2Off : SIconTrash2
88
- }
89
-
90
- throw new Error(`[sefirot] Invalid icon type: ${icon}.`)
91
- }
92
-
93
- function handleCallback(action: Action): void {
94
- if (action.disabled) {
95
- return
96
- }
97
-
98
- if (action.link) {
99
- router.push(action.link)
100
- return
101
- }
102
-
103
- action.callback?.()
104
- }
105
-
106
- return {
107
- classes,
108
- unwrapedActions,
109
- getIcon,
110
- handleCallback
111
- }
112
- }
113
- })
114
- </script>
115
-
116
- <style lang="postcss" scoped>
117
- @import "@/assets/styles/variables";
118
-
119
- .SCardHeader {
120
- display: flex;
121
- padding: 8px 8px 7px 16px;
122
- border-bottom: 1px solid var(--c-divider-light);
123
- background-color: var(--card-bg-mute);
124
- }
125
-
126
- .SCardHeader.collapsed {
127
- border-bottom-color: transparent;
128
- }
129
-
130
- .SCardHeader.collapsed .collapse {
131
- transform: rotate(0);
132
- }
133
-
134
- .SCardHeader.collapsed .collapse-icon {
135
- transform: translateY(1px);
136
- }
137
-
138
- .SCardHeader.round-0 { border-radius: none; }
139
- .SCardHeader.round-4 { border-radius: 4px 4px 0 0; }
140
- .SCardHeader.round-8 { border-radius: 8px 8px 0 0; }
141
-
142
- .title {
143
- flex-grow: 1;
144
- }
145
-
146
- .title-text {
147
- line-height: 32px;
148
- font-size: 14px;
149
- font-weight: 500;
150
- }
151
-
152
- .actions {
153
- display: flex;
154
- }
155
-
156
- .action {
157
- display: flex;
158
- justify-content: center;
159
- align-items: center;
160
- flex-shrink: 0;
161
- border-radius: 4px;
162
- width: 32px;
163
- height: 32px;
164
- color: var(--c-text-2);
165
- cursor: pointer;
166
- transition: color .25s, background-color .25s;
167
-
168
- &:hover {
169
- background-color: var(--c-gray-light-4);
170
- }
171
- }
172
-
173
- .action.neutral:hover { color: var(--c-text-1); }
174
- .action.info:hover { color: var(--c-info); }
175
- .action.success:hover { color: var(--c-success); }
176
- .action.warning:hover { color: var(--c-warning); }
177
- .action.danger:hover { color: var(--c-danger); }
178
-
179
- .action.disabled:hover {
180
- color: var(--c-text-2);
181
- background-color: transparent;
182
- cursor: not-allowed;
183
- }
184
-
185
- .action-icon {
186
- width: 16px;
187
- height: 16px;
188
- fill: currentColor;
189
- }
190
-
191
- .collapse {
192
- display: flex;
193
- justify-content: center;
194
- align-items: center;
195
- border-radius: 4px;
196
- width: 32px;
197
- height: 32px;
198
- color: var(--c-text-3);
199
- transform: rotate(180deg);
200
- transition: color .25s, background-color .25s;
201
-
202
- &:hover {
203
- color: var(--c-text-2);
204
- background-color: var(--c-gray-light-4);
205
- }
206
- }
207
-
208
- .collapse-icon {
209
- width: 20px;
210
- height: 20px;
211
- fill: currentColor;
212
- }
213
- </style>