@propelinc/citrus-ui 0.1.1 → 0.2.1

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 (71) hide show
  1. package/dist/citrus-ui.common.js +1149 -187
  2. package/dist/citrus-ui.common.js.map +1 -1
  3. package/dist/citrus-ui.css +1 -1
  4. package/dist/citrus-ui.umd.js +1149 -187
  5. package/dist/citrus-ui.umd.js.map +1 -1
  6. package/dist/citrus-ui.umd.min.js +4 -4
  7. package/dist/citrus-ui.umd.min.js.map +1 -1
  8. package/dist/fonts/Blitz-Script.85ed9abe.woff2 +0 -0
  9. package/jest.config.js +5 -0
  10. package/package.json +4 -3
  11. package/src/assets/fonts/Blitz-Script.woff2 +0 -0
  12. package/src/components/CButton.vue +68 -22
  13. package/src/components/CSegmentedButton.vue +46 -0
  14. package/src/components/CSegmentedButtonOption.vue +45 -0
  15. package/src/components/CSelect.vue +67 -0
  16. package/src/components/CTextField.vue +15 -62
  17. package/src/components/helpers/FormField.vue +40 -0
  18. package/src/components/helpers/SelectInput.vue +112 -0
  19. package/src/index.d.ts +3 -0
  20. package/src/index.ts +6 -0
  21. package/src/styles/blitz.less +8 -0
  22. package/src/styles/core.less +1 -0
  23. package/src/styles/form-fields.less +46 -0
  24. package/src/styles/typography.less +8 -0
  25. package/src/styles/variables.less +8 -0
  26. package/storybook-static/0.0ebc4b6e.iframe.bundle.js +1 -0
  27. package/storybook-static/0.1db6407b6f251cb99757.manager.bundle.js +1 -0
  28. package/storybook-static/1.08e48cd2b295b33abac5.manager.bundle.js +1 -0
  29. package/storybook-static/10.58b60afe35d013b05f26.manager.bundle.js +1 -0
  30. package/storybook-static/11.7f35c06cd77f40a88403.manager.bundle.js +2 -0
  31. package/storybook-static/11.7f35c06cd77f40a88403.manager.bundle.js.LICENSE.txt +12 -0
  32. package/storybook-static/12.2f8d9cc3bdcfbb59dabf.manager.bundle.js +1 -0
  33. package/storybook-static/4.99a2e548.iframe.bundle.js +3 -0
  34. package/storybook-static/4.99a2e548.iframe.bundle.js.LICENSE.txt +8 -0
  35. package/storybook-static/4.99a2e548.iframe.bundle.js.map +1 -0
  36. package/storybook-static/5.146a98dc.iframe.bundle.js +1 -0
  37. package/storybook-static/5.4d5248d1e985d19512e5.manager.bundle.js +2 -0
  38. package/storybook-static/5.4d5248d1e985d19512e5.manager.bundle.js.LICENSE.txt +8 -0
  39. package/storybook-static/6.297d139ca80380169c9a.manager.bundle.js +1 -0
  40. package/storybook-static/6.4c77ef89.iframe.bundle.js +3 -0
  41. package/storybook-static/6.4c77ef89.iframe.bundle.js.LICENSE.txt +12 -0
  42. package/storybook-static/6.4c77ef89.iframe.bundle.js.map +1 -0
  43. package/storybook-static/7.1dd6103d8c4adf231b89.manager.bundle.js +1 -0
  44. package/storybook-static/7.414cf1e4.iframe.bundle.js +1 -0
  45. package/storybook-static/8.0c32e96f86b87a58d415.manager.bundle.js +1 -0
  46. package/storybook-static/9.da52dd791e7234e0495a.manager.bundle.js +1 -0
  47. package/storybook-static/css/main.918ac2bc.css +1 -0
  48. package/storybook-static/css/vendors~main.ec1b1c6e.css +1 -0
  49. package/storybook-static/favicon.ico +0 -0
  50. package/storybook-static/fonts/ObjectSans-Black.314082dd.woff2 +0 -0
  51. package/storybook-static/fonts/ObjectSans-BlackSlanted.d3163c50.woff2 +0 -0
  52. package/storybook-static/fonts/ObjectSans-Bold.5492f3d5.woff2 +0 -0
  53. package/storybook-static/fonts/ObjectSans-BoldSlanted.29e2a87e.woff2 +0 -0
  54. package/storybook-static/fonts/ObjectSans-Heavy.d0b2f035.woff2 +0 -0
  55. package/storybook-static/fonts/ObjectSans-HeavySlanted.45e9c063.woff2 +0 -0
  56. package/storybook-static/fonts/ObjectSans-Regular.e4ea0b90.woff2 +0 -0
  57. package/storybook-static/fonts/ObjectSans-Slanted.57a90be9.woff2 +0 -0
  58. package/storybook-static/fonts/ObjectSans-Thin.86d44227.woff2 +0 -0
  59. package/storybook-static/fonts/ObjectSans-ThinSlanted.20342160.woff2 +0 -0
  60. package/storybook-static/iframe.html +133 -0
  61. package/storybook-static/index.html +47 -0
  62. package/storybook-static/main.4c454d37.iframe.bundle.js +1 -0
  63. package/storybook-static/main.57da3f9fe16e02557812.manager.bundle.js +1 -0
  64. package/storybook-static/runtime~main.335986b66fb5bcf65138.manager.bundle.js +1 -0
  65. package/storybook-static/runtime~main.b29ddaa7.iframe.bundle.js +1 -0
  66. package/storybook-static/vendors~main.0b7555aaeb5d052c07aa.manager.bundle.js +2 -0
  67. package/storybook-static/vendors~main.0b7555aaeb5d052c07aa.manager.bundle.js.LICENSE.txt +88 -0
  68. package/storybook-static/vendors~main.4d3a0ad4.iframe.bundle.js +3 -0
  69. package/storybook-static/vendors~main.4d3a0ad4.iframe.bundle.js.LICENSE.txt +128 -0
  70. package/storybook-static/vendors~main.4d3a0ad4.iframe.bundle.js.map +1 -0
  71. package/tsconfig.json +2 -1
package/jest.config.js CHANGED
@@ -1,4 +1,9 @@
1
1
  module.exports = {
2
2
  preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
3
3
  setupFilesAfterEnv: ['<rootDir>/tests/unit/helpers/custom-matchers.ts'],
4
+
5
+ transformIgnorePatterns: ['<rootDir>/node_modules/(?!vuetify/lib)'],
6
+ moduleNameMapper: {
7
+ '^.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
8
+ },
4
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@propelinc/citrus-ui",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/propelinc/citrus-ui"
@@ -12,8 +12,9 @@
12
12
  "lint": "npm run lint:js && npm run lint:css",
13
13
  "lint:css": "stylelint \"src/**/*.(vue|less)\"",
14
14
  "lint:js": "vue-cli-service lint",
15
- "storybook:build": "vue-cli-service storybook:build -c config/storybook",
16
- "storybook:serve": "vue-cli-service storybook:serve -p 6006 -c config/storybook",
15
+ "publish": "npm run build:dist && npm publish",
16
+ "storybook:build": "vue-cli-service storybook:build -c .storybook",
17
+ "storybook:serve": "vue-cli-service storybook:serve -p 6006 -c .storybook",
17
18
  "storybook:publish": "storybook-to-aws-s3 --script=\"storybook:build\" --bucket-path=citrus-ui-storybook",
18
19
  "test:unit": "vue-cli-service test:unit"
19
20
  },
@@ -2,18 +2,23 @@
2
2
  <v-btn
3
3
  class="button"
4
4
  :class="{
5
+ 'button--primary': !secondary && !tertiary,
5
6
  'button--secondary': secondary,
7
+ 'button--tertiary': tertiary,
8
+ 'button--dark': dark,
9
+ 'button--light': light,
6
10
  'button--large': large,
7
- [`${colorScheme.text}--text`]: true,
11
+ 'button--disabled': disabled,
8
12
  }"
9
13
  data-test="button"
10
14
  rounded
11
15
  :block="block"
12
16
  :elevation="0"
13
- :color="colorScheme.container"
14
17
  :large="large"
15
18
  :ripple="false"
16
19
  :to="to"
20
+ :text="tertiary"
21
+ :disabled="disabled"
17
22
  v-on="$listeners"
18
23
  >
19
24
  <div v-if="hasIcon" class="button__icon">
@@ -32,30 +37,18 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
32
37
  import { Component, Vue, Prop } from 'vue-property-decorator';
33
38
  import { RawLocation } from 'vue-router';
34
39
 
35
- interface ColorScheme {
36
- text: string;
37
- container: string;
38
- }
39
-
40
40
  @Component({ name: 'CButton', components: { FontAwesomeIcon } })
41
- export default class Button extends Vue {
42
- @Prop({ type: Boolean, default: false }) dark!: boolean;
41
+ export default class CButton extends Vue {
43
42
  @Prop({ type: Boolean, default: false }) block!: boolean;
43
+ @Prop({ type: Boolean, default: false }) dark!: boolean;
44
+ @Prop({ type: Boolean, default: false }) disabled!: boolean;
45
+ @Prop([String, Array, Object]) icon?: IconDefinition;
44
46
  @Prop({ type: Boolean, default: false }) large!: boolean;
47
+ @Prop({ type: Boolean, default: false }) light!: boolean;
45
48
  @Prop({ type: Boolean, default: false }) secondary!: boolean;
46
- @Prop([String, Array, Object]) icon?: IconDefinition;
49
+ @Prop({ type: Boolean, default: false }) tertiary!: boolean;
47
50
  @Prop([Object, String]) to?: RawLocation;
48
51
 
49
- get colorScheme(): ColorScheme {
50
- if (this.dark) {
51
- return { text: 'white', container: 'navy' };
52
- } else if (this.secondary) {
53
- return { text: 'primary', container: 'white' };
54
- } else {
55
- return { text: 'white', container: 'primary' };
56
- }
57
- }
58
-
59
52
  get hasIcon(): boolean {
60
53
  return !!(this.icon || this.$slots.icon || this.$scopedSlots.icon);
61
54
  }
@@ -75,12 +68,65 @@ export default class Button extends Vue {
75
68
  }
76
69
  }
77
70
 
78
- .button--large {
79
- font-size: 16px;
71
+ .button--primary {
72
+ background-color: @color-blue-accent !important;
73
+ color: @color-white;
74
+ }
75
+
76
+ .button--primary.button--dark {
77
+ background-color: @color-navy !important;
78
+ }
79
+
80
+ .button--primary.button--light {
81
+ background-color: @color-white !important;
82
+ color: @color-navy;
80
83
  }
81
84
 
82
85
  .button--secondary {
83
86
  border: @border !important;
87
+ color: @color-blue-accent;
88
+ }
89
+
90
+ .button--secondary.button--dark {
91
+ color: @color-navy;
92
+ }
93
+
94
+ .button--secondary.button--light {
95
+ background-color: @color-navy !important;
96
+ color: @color-white;
97
+ }
98
+
99
+ .button--tertiary {
100
+ color: @color-blue-accent;
101
+ }
102
+
103
+ .button--tertiary.button--dark {
104
+ color: @color-navy;
105
+ }
106
+
107
+ .button--tertiary.button--light {
108
+ color: @color-white;
109
+ }
110
+
111
+ // Add some insane specificity to override Vuetify.
112
+ .theme--light.v-btn.v-btn--disabled:not(.v-btn--outlined) {
113
+ &.button--disabled.button--primary {
114
+ background-color: @color-navy-tint-4 !important;
115
+ color: @color-navy-tint-1 !important;
116
+ }
117
+
118
+ &.button--disabled.button--secondary {
119
+ background-color: @color-white !important;
120
+ color: @color-navy-tint-2 !important;
121
+ }
122
+
123
+ &.button--disabled.button--tertiary {
124
+ color: @color-navy-tint-2 !important;
125
+ }
126
+ }
127
+
128
+ .button--large {
129
+ font-size: 16px;
84
130
  }
85
131
 
86
132
  .button__icon {
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <v-btn-toggle
3
+ data-test="segmented-button"
4
+ :value="value"
5
+ rounded
6
+ class="segmented-button"
7
+ active-class="segmented-button__option--active"
8
+ @change="(value) => $emit('change', value)"
9
+ >
10
+ <slot>
11
+ <c-segmented-button-option
12
+ v-for="option in options"
13
+ :key="option.label"
14
+ :value="option.value"
15
+ :label="option.label"
16
+ />
17
+ </slot>
18
+ </v-btn-toggle>
19
+ </template>
20
+
21
+ <script lang="ts">
22
+ import { Component, Vue, Prop } from 'vue-property-decorator';
23
+
24
+ import CSegmentedButtonOption from '@/components/CSegmentedButtonOption.vue';
25
+
26
+ interface SegmentedButtonOption {
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ value: any;
29
+ label: string;
30
+ }
31
+
32
+ @Component({ name: 'CSegmentedButton', components: { CSegmentedButtonOption } })
33
+ export default class CSegmentedButton extends Vue {
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
+ @Prop() value?: any;
36
+ @Prop({ type: Array, required: true }) options!: SegmentedButtonOption[];
37
+ }
38
+ </script>
39
+
40
+ <style lang="less" scoped>
41
+ @import '~@/styles/variables.less';
42
+
43
+ .segmented-button {
44
+ width: 100%;
45
+ }
46
+ </style>
@@ -0,0 +1,45 @@
1
+ <template>
2
+ <v-btn
3
+ class="segmented-button__option"
4
+ data-test="segmented-button-option"
5
+ :ripple="false"
6
+ :value="value"
7
+ >
8
+ <slot>
9
+ {{ label }}
10
+ </slot>
11
+ </v-btn>
12
+ </template>
13
+
14
+ <script lang="ts">
15
+ import { Component, Vue, Prop } from 'vue-property-decorator';
16
+
17
+ @Component({ name: 'CSegmentedButtonOption' })
18
+ export default class CSegmentedButtonOption extends Vue {
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ @Prop({ required: true }) value?: any;
21
+ @Prop(String) label?: string;
22
+ }
23
+ </script>
24
+
25
+ <style lang="less" scoped>
26
+ @import '~@/styles/variables.less';
27
+
28
+ .segmented-button__option {
29
+ border: @border !important;
30
+ color: @color-navy;
31
+ flex: 1 1 0;
32
+ font-weight: @font-weight-heavy;
33
+ letter-spacing: 0;
34
+ text-transform: none;
35
+
36
+ &::before {
37
+ color: transparent;
38
+ }
39
+ }
40
+
41
+ // This class is applied by the CSegmentedButton component.
42
+ .segmented-button__option--active {
43
+ background-color: @color-blue !important;
44
+ }
45
+ </style>
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <form-field :field-id="id" :disabled="disabled" :label="label">
3
+ <select-input
4
+ :id="id"
5
+ v-bind="$attrs"
6
+ data-test="select-field"
7
+ class="select__field"
8
+ :class="{ 'select__field--disabled': disabled }"
9
+ outlined
10
+ single-line
11
+ :placeholder="placeholder"
12
+ :disabled="disabled"
13
+ :value="value"
14
+ :rules="rules"
15
+ :items="items"
16
+ validate-on-blur
17
+ hide-details="auto"
18
+ @input="(value) => $emit('input', value)"
19
+ >
20
+ <template #append>
21
+ <font-awesome-icon
22
+ v-if="loading"
23
+ data-test="select-field-icon-loading"
24
+ :icon="faSpinner"
25
+ class="fa-spin"
26
+ />
27
+ <font-awesome-icon v-else data-test="select-field-icon" :icon="faChevronDown" />
28
+ </template>
29
+ </select-input>
30
+ </form-field>
31
+ </template>
32
+
33
+ <script lang="ts">
34
+ import { faChevronDown, faSpinner } from '@fortawesome/pro-light-svg-icons';
35
+ import { Component, Vue, Prop } from 'vue-property-decorator';
36
+
37
+ import FormField from '@/components/helpers/FormField.vue';
38
+ import SelectInput from '@/components/helpers/SelectInput.vue';
39
+
40
+ // @ts-ignore
41
+ @Component({ name: 'CSelect', components: { FormField, SelectInput } })
42
+ export default class CSelect extends Vue {
43
+ faChevronDown = faChevronDown;
44
+ faSpinner = faSpinner;
45
+
46
+ @Prop(String) label?: string;
47
+ @Prop(String) placeholder?: string;
48
+ @Prop({ type: String, required: true }) id!: string;
49
+ @Prop({ type: Array, default: () => [] }) items!: { label: string; value: string }[];
50
+ @Prop({ type: Boolean, default: false }) disabled!: boolean;
51
+ @Prop({ type: String, default: '' }) value!: string;
52
+ @Prop({ type: Boolean, default: false }) loading!: boolean;
53
+ @Prop({ type: Array, default: () => [] }) rules!: ((value: string) => string | boolean)[];
54
+ }
55
+ </script>
56
+
57
+ <style lang="less" scoped>
58
+ @import '~@/styles/form-fields.less';
59
+
60
+ .select__field {
61
+ .form-field();
62
+ }
63
+
64
+ .select__field--disabled {
65
+ .form-field-disabled();
66
+ }
67
+ </style>
@@ -1,15 +1,5 @@
1
1
  <template>
2
- <fieldset :disabled="disabled">
3
- <label
4
- v-if="label"
5
- :for="id"
6
- data-test="text-field-label"
7
- class="text-field__label"
8
- :class="{ 'text-field__label--disabled': disabled }"
9
- >
10
- {{ label }}
11
- </label>
12
-
2
+ <form-field :field-id="id" :disabled="disabled" :label="label">
13
3
  <v-text-field
14
4
  :id="id"
15
5
  v-bind="$attrs"
@@ -26,76 +16,39 @@
26
16
  validate-on-blur
27
17
  hide-details="auto"
28
18
  @input="(value) => $emit('input', value)"
29
- />
30
- </fieldset>
19
+ >
20
+ <template #append>
21
+ <slot name="append" />
22
+ </template>
23
+ </v-text-field>
24
+ </form-field>
31
25
  </template>
32
26
 
33
27
  <script lang="ts">
34
28
  import { Component, Vue, Prop } from 'vue-property-decorator';
35
29
 
36
- @Component({ name: 'CTextField' })
30
+ import FormField from '@/components/helpers/FormField.vue';
31
+
32
+ @Component({ name: 'CTextField', components: { FormField } })
37
33
  export default class CTextField extends Vue {
38
34
  @Prop(String) label?: string;
39
35
  @Prop(String) placeholder?: string;
40
36
  @Prop({ type: String, required: true }) id!: string;
41
37
  @Prop({ type: String, default: 'text' }) type!: string;
42
38
  @Prop({ type: Boolean, default: false }) disabled!: boolean;
43
- @Prop({ type: String, default: '' }) value!: boolean;
44
- @Prop(Array) rules?: ((value: string) => string | boolean)[];
39
+ @Prop({ type: String, default: '' }) value!: string;
40
+ @Prop({ type: Array, default: () => [] }) rules!: ((value: string) => string | boolean)[];
45
41
  }
46
42
  </script>
47
43
 
48
44
  <style lang="less" scoped>
49
- @import '~@/styles/variables.less';
50
-
51
- @color-disabled-text: @color-navy-tint-2;
52
-
53
- .text-field__label {
54
- font-weight: @font-weight-bold;
55
- margin: 0 0 4px 2px;
56
- }
57
-
58
- .text-field__label--disabled {
59
- color: @color-disabled-text;
60
- }
45
+ @import '~@/styles/form-fields.less';
61
46
 
62
47
  .text-field__field {
63
- & /deep/ legend {
64
- display: none;
65
- }
66
-
67
- &.v-input--is-focused /deep/ fieldset,
68
- &.v-input--has-state /deep/ fieldset {
69
- border-color: currentColor;
70
- border-width: 1px;
71
- }
72
-
73
- & /deep/ .v-input__slot {
74
- min-height: 48px;
75
- padding: 0 16px !important; // Override Vuetify.
76
- }
77
-
78
- & /deep/ input {
79
- .body();
80
-
81
- line-height: 20px;
82
- }
83
- }
84
-
85
- /deep/ fieldset {
86
- background: @color-white;
87
- border-color: @color-neutral-shade;
88
- border-radius: @border-radius;
89
- top: 0;
48
+ .form-field();
90
49
  }
91
50
 
92
51
  .text-field__field--disabled {
93
- & /deep/ fieldset {
94
- background: @color-neutral-shade;
95
- }
96
-
97
- & /deep/ input {
98
- color: @color-disabled-text;
99
- }
52
+ .form-field-disabled();
100
53
  }
101
54
  </style>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <fieldset :disabled="disabled">
3
+ <label
4
+ v-if="label"
5
+ :for="fieldId"
6
+ data-test="form-field-label"
7
+ class="form-field__label"
8
+ :class="{ 'form-field__label--disabled': disabled }"
9
+ >
10
+ {{ label }}
11
+ </label>
12
+
13
+ <slot />
14
+ </fieldset>
15
+ </template>
16
+
17
+ <script lang="ts">
18
+ import { Component, Vue, Prop } from 'vue-property-decorator';
19
+
20
+ @Component({ name: 'FormField' })
21
+ export default class FormField extends Vue {
22
+ @Prop(String) label?: string;
23
+ @Prop({ type: String, required: true }) fieldId!: string;
24
+ @Prop({ type: Boolean, default: false }) disabled!: boolean;
25
+ }
26
+ </script>
27
+
28
+ <style lang="less" scoped>
29
+ @import '~@/styles/variables.less';
30
+ @import '~@/styles/form-fields.less';
31
+
32
+ .form-field__label {
33
+ font-weight: @font-weight-bold;
34
+ margin: 0 0 4px 2px;
35
+ }
36
+
37
+ .form-field__label--disabled {
38
+ color: @color-disabled-text;
39
+ }
40
+ </style>
@@ -0,0 +1,112 @@
1
+ <script>
2
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
3
+
4
+ /**
5
+ * NOTE(mohan): This component is meant to be an alternative to VSelect that uses native
6
+ * <select/> tags.
7
+ *
8
+ * Because Vuetify uses its implementation of a dropdown that imitates a desktop menu,
9
+ * it's hard to use on mobile. This component replaces the inner <input> of a VTextField
10
+ * with a <select/> so that we can use continue to use all of the nice Vuetify features while also
11
+ * having a native <select/>.
12
+ *
13
+ * See: https://github.com/vuetifyjs/vuetify/issues/4059. */
14
+ import { VTextField } from 'vuetify/lib';
15
+
16
+ export default {
17
+ name: 'SelectInput',
18
+ extends: VTextField,
19
+
20
+ props: {
21
+ items: {
22
+ type: Array,
23
+ default: () => [],
24
+ },
25
+ placeholder: {
26
+ type: String,
27
+ default: null,
28
+ },
29
+ },
30
+
31
+ methods: {
32
+ genInput() {
33
+ const listeners = { ...this.listeners$ };
34
+ delete listeners.change; // Change should not be bound externally
35
+
36
+ return this.$createElement(
37
+ 'select',
38
+ {
39
+ style: {},
40
+ domProps: {
41
+ value: this.lazyValue,
42
+ },
43
+ attrs: {
44
+ ...this.attrs$,
45
+ autofocus: this.autofocus,
46
+ disabled: this.disabled,
47
+ id: this.computedId,
48
+ readonly: this.readonly,
49
+ },
50
+ class: !this.isDirty ? 'select-input--placeholder' : undefined,
51
+ on: {
52
+ ...listeners,
53
+ blur: this.onBlur,
54
+ input: this.onInput,
55
+ focus: this.onFocus,
56
+ keydown: this.onKeyDown,
57
+ },
58
+ ref: 'input',
59
+ },
60
+ this.genOptions()
61
+ );
62
+ },
63
+
64
+ genOptions() {
65
+ let options = this.items.map((item) => {
66
+ return this.$createElement('option', {
67
+ domProps: {
68
+ innerHTML: item.label,
69
+ value: item.value,
70
+ },
71
+ });
72
+ });
73
+ if (this.placeholder) {
74
+ options = [
75
+ this.$createElement('option', {
76
+ domProps: {
77
+ innerHTML: this.placeholder,
78
+ value: '',
79
+ hidden: true,
80
+ disabled: true,
81
+ selected: true,
82
+ },
83
+ }),
84
+ ...options,
85
+ ];
86
+ }
87
+ return options;
88
+ },
89
+ },
90
+ };
91
+ </script>
92
+
93
+ <style lang="less" scoped>
94
+ @import '~@/styles/variables.less';
95
+
96
+ select {
97
+ color: @color-navy;
98
+ cursor: pointer;
99
+ height: 100%;
100
+ position: absolute;
101
+ width: 100%;
102
+ z-index: 1;
103
+ }
104
+
105
+ select:focus {
106
+ outline: none;
107
+ }
108
+
109
+ .select-input--placeholder {
110
+ color: @color-navy-tint-3;
111
+ }
112
+ </style>
package/src/index.d.ts CHANGED
@@ -10,6 +10,9 @@ export const CCard: Component;
10
10
  export const CIconButton: Component;
11
11
  export const CListItem: Component;
12
12
  export const CModalLoading: Component;
13
+ export const CSegmentedButton: Component;
14
+ export const CSegmentedButtonOption: Component;
15
+ export const CSelect: Component;
13
16
  export const CSkeletonLoaderCircle: Component;
14
17
  export const CSkeletonLoaderText: Component;
15
18
  export const CTextField: Component;
package/src/index.ts CHANGED
@@ -7,6 +7,9 @@ import _CCard from '@/components/CCard.vue';
7
7
  import _CIconButton from '@/components/CIconButton.vue';
8
8
  import _CListItem from '@/components/CListItem.vue';
9
9
  import _CModalLoading from '@/components/CModalLoading.vue';
10
+ import _CSegmentedButton from '@/components/CSegmentedButton.vue';
11
+ import _CSegmentedButtonOption from '@/components/CSegmentedButtonOption.vue';
12
+ import _CSelect from '@/components/CSelect.vue';
10
13
  import _CSkeletonLoaderCircle from '@/components/CSkeletonLoaderCircle.vue';
11
14
  import _CSkeletonLoaderText from '@/components/CSkeletonLoaderText.vue';
12
15
  import _CTextField from '@/components/CTextField.vue';
@@ -23,6 +26,9 @@ export const CCard = _CCard;
23
26
  export const CIconButton = _CIconButton;
24
27
  export const CListItem = _CListItem;
25
28
  export const CModalLoading = _CModalLoading;
29
+ export const CSegmentedButton = _CSegmentedButton;
30
+ export const CSegmentedButtonOption = _CSegmentedButtonOption;
31
+ export const CSelect = _CSelect;
26
32
  export const CSkeletonLoaderCircle = _CSkeletonLoaderCircle;
27
33
  export const CSkeletonLoaderText = _CSkeletonLoaderText;
28
34
  export const CTextField = _CTextField;
@@ -0,0 +1,8 @@
1
+ @import "./variables.less";
2
+
3
+ @font-face {
4
+ font-family: @font-family-blitz;
5
+ font-style: normal;
6
+ font-weight: @font-weight-normal;
7
+ src: url('../assets/fonts/Blitz-Script.woff2') format('woff2'),
8
+ }
@@ -1,4 +1,5 @@
1
1
  @import './object-sans.less';
2
+ @import './blitz.less';
2
3
 
3
4
  .provide.provide-theme {
4
5
  /* stylelint-disable-next-line no-invalid-position-at-import-rule */
@@ -0,0 +1,46 @@
1
+ @import '~@/styles/variables.less';
2
+
3
+ @color-disabled-text: @color-navy-tint-2;
4
+
5
+ .form-field() {
6
+ & /deep/ legend {
7
+ display: none;
8
+ }
9
+
10
+ &.v-input--is-focused /deep/ fieldset,
11
+ &.v-input--has-state /deep/ fieldset {
12
+ border-color: currentColor;
13
+ border-width: 1px;
14
+ }
15
+
16
+ & /deep/ .v-input__slot {
17
+ min-height: 48px;
18
+ padding: 0 16px !important; // Override Vuetify.
19
+ }
20
+
21
+ & /deep/ input,
22
+ & /deep/ select {
23
+ .body();
24
+
25
+ line-height: 20px;
26
+ }
27
+
28
+ /deep/ fieldset {
29
+ background: @color-white;
30
+ border-color: @color-neutral-shade;
31
+ border-radius: @border-radius;
32
+ top: 0;
33
+ z-index: -1;
34
+ }
35
+ }
36
+
37
+ .form-field-disabled() {
38
+ & /deep/ fieldset {
39
+ background: @color-neutral-shade;
40
+ }
41
+
42
+ & /deep/ input,
43
+ & /deep/ select {
44
+ color: @color-disabled-text;
45
+ }
46
+ }