jobdone-shared-files 1.0.13 → 1.0.14

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 (32) hide show
  1. package/ProjectManagement/projectNavbar.vue +363 -363
  2. package/autocompleteSelect.vue +461 -461
  3. package/common/directives/collapse.js +12 -12
  4. package/common/directives/popovers.js +10 -10
  5. package/common/directives/selectPlaceholder.js +52 -52
  6. package/common/directives/textareaAutoHeight.js +10 -10
  7. package/common/directives/tooltip.js +10 -10
  8. package/common/format.js +26 -26
  9. package/index.js +14 -14
  10. package/lightboxWithOverview.vue +156 -156
  11. package/package.json +19 -19
  12. package/paginate.vue +141 -141
  13. package/style/css/vue-loading-overlay/index.css +40 -40
  14. package/style/scss/Common/Animation.scss +9 -9
  15. package/style/scss/Common/SelectableTable.scss +34 -34
  16. package/style/scss/Common/filepond.scss +31 -31
  17. package/style/scss/Common/thumbnail-group.scss +14 -14
  18. package/style/scss/Layout/LayoutBase.scss +1031 -1031
  19. package/style/scss/Layout/LayoutMobile.scss +206 -206
  20. package/style/scss/Layout/LayoutProject.scss +126 -126
  21. package/style/scss/Layout/LayoutSinglePage.scss +17 -17
  22. package/style/scss/Layout/LayoutTwoColumn.scss +60 -60
  23. package/style/scss/Settings/_Mixins.scss +232 -232
  24. package/style/scss/Settings/_MobileVariables.scss +11 -11
  25. package/style/scss/Settings/_bs-variables-dark.scss +70 -70
  26. package/style/scss/Settings/_bs-variables.scss +1743 -1743
  27. package/style/scss/Settings/_color-mode.scss +122 -122
  28. package/style/scss/Settings/_custom-variables.scss +10 -10
  29. package/tagEditor.vue +249 -249
  30. package/tree.vue +69 -69
  31. package/treeItem.vue +355 -371
  32. package/vueLoadingOverlay.vue +74 -74
@@ -1,1032 +1,1032 @@
1
- // ====================================
2
- // Plugin
3
- // ====================================
4
-
5
- // Custom Bootstrap
6
- @import "../../../../bootstrap/scss/functions";
7
- @import "../Settings/bs-variables";
8
- @import "../../../../bootstrap/scss/bootstrap.scss";
9
-
10
-
11
- // ====================================
12
- // Helpers
13
- // ====================================
14
-
15
- // Mixins
16
- @import "../Settings/Mixins";
17
-
18
-
19
- // ====================================
20
- // Custom Style
21
- // ====================================
22
-
23
- @import "../Settings/color-mode";
24
- @import "../Settings/custom-variables";
25
-
26
-
27
- @mixin gradient-bg(){
28
- &:before{
29
- content: "";
30
- display: block;
31
- @include position-center();
32
- z-index: 0;
33
- background: $gradient-blue-light;
34
- pointer-events: none;
35
- transition: $transition-base;
36
- }
37
- }
38
-
39
- @mixin gradient-bg-hover-to-show($opacity: 1){
40
- @include gradient-bg();
41
- &:before{ opacity: 0; }
42
- &:hover:before{ opacity: $opacity; }
43
- }
44
-
45
- // general ------------------------------------------
46
- :root{
47
- --backdrop-blur: blur(2px);
48
-
49
- // ====================================
50
- // scrollbar樣式
51
- // ====================================
52
- --scrollbar-width: 10px;
53
- }
54
-
55
- [v-cloak]{
56
- display: none !important;
57
- }
58
-
59
- html,
60
- .overflow-auto, .overflow-scroll,
61
- .overflow-y-auto, .overflow-y-scroll,
62
- .offcanvas-body, textarea{
63
- @include scrollbar();
64
- transition: $transition-base;
65
- }
66
-
67
- .overflow-x-auto, .overflow-x-scroll, .scrollbar-sm, .table-responsive{
68
- @include scrollbar();
69
- --scrollbar-width: 6px;
70
- overflow-x: auto;
71
- -webkit-overflow-scrolling: touch;
72
- }
73
-
74
- .scrollbar-gutter-stable{
75
- // Safari 暫不支援
76
- scrollbar-gutter: stable;
77
- }
78
-
79
- body{
80
- background-color: var(--gray-200);
81
- --maz-color-primary: var(--bs-primary);
82
- --maz-color-secondary: var(--bs-secondary);
83
- --maz-color-info: var(--bs-info);
84
- --maz-color-success: var(--bs-success);
85
- --maz-color-warning: var(--bs-warning);
86
- --maz-color-danger: var(--bs-danger);
87
- --maz-color-bg: var(--bs-body-bg);
88
- --maz-color-text: var(--bs-body-color);
89
- --maz-color-muted: var(--bs-secondary-color);
90
- }
91
-
92
- ul, ol{
93
- &.list-reset{
94
- list-style-type: none;
95
- padding-left: 0;
96
- }
97
- }
98
- // general ------------------------------------------
99
-
100
-
101
- // text / link ------------------------------------------
102
- a{
103
- text-decoration: none;
104
- // 如果需要底線使用 <u></u> tag
105
- transition: $transition-base;
106
- &.a-reset-color{
107
- color: inherit;
108
- }
109
- &.a-hover-gradient{
110
- position: relative;
111
- @include gradient-bg-hover-to-show();
112
- }
113
- }
114
-
115
- .text-link{
116
- color: var(--bs-link-color);
117
- &:hover{
118
- color: var(--bs-link-hover-color);
119
- }
120
- }
121
-
122
- .text-pre-wrap{
123
- white-space: pre-wrap;
124
- }
125
-
126
- .fs-min{
127
- font-size: 12px;
128
- }
129
-
130
- .text-overflow{
131
- @include text-overflow();
132
- }
133
-
134
- @for $i from 1 through 5 {
135
- .text-line-clamp-#{$i} {
136
- @include text-line-clamp(#{$i});
137
- }
138
- }
139
-
140
- @for $i from 1 through 5 {
141
- .letter-spacing-#{$i} {
142
- letter-spacing: #{$i}px;
143
- }
144
- }
145
-
146
- // text / link ------------------------------------------
147
-
148
-
149
- // border ------------------------------------------
150
- .hover-border{
151
- transition: $transition-base;
152
- &:hover{
153
- box-shadow: $focus-ring-box-shadow;
154
- }
155
- }
156
- .active-border{
157
- box-shadow: $focus-ring-box-shadow;
158
- }
159
- // border ------------------------------------------
160
-
161
-
162
- // badge outline ------------------------------------------
163
-
164
- @each $color, $value in $colors {
165
- .badge-outline-#{$color}{
166
- color: $value;
167
- border: $border-width solid rgba($value, .5);
168
- background-color: rgba($value, .1);
169
- }
170
- }
171
-
172
- // badge outline ------------------------------------------
173
-
174
-
175
- // input ------------------------------------------
176
- .form-control{
177
- caret-color: $primary;
178
- }
179
- // input ------------------------------------------
180
-
181
-
182
- // checkbox / radio ------------------------------------------
183
-
184
- .check-label{
185
- cursor: pointer;
186
- &, &:before, span{
187
- vertical-align: middle;
188
- transition: $transition-base;
189
- }
190
- &:before{
191
- content: "check_box_outline_blank";
192
- display: inline-block;
193
- margin-right: .1em;
194
- color: var(--gray-500);
195
- font-family: 'Material Icons';
196
- font-size: 120%;
197
- line-height: inherit;
198
- white-space: nowrap;
199
- -webkit-font-feature-settings: 'liga';
200
- -webkit-font-smoothing: antialiased;
201
- }
202
- &:not(.badge):hover{
203
- &, &:before, span{
204
- color: $primary;
205
- }
206
- }
207
- }
208
-
209
- .check-group{
210
- position: relative;
211
- display: inline-block;
212
- vertical-align: middle;
213
- &:not(:last-child){
214
- margin-right: 1em;
215
- }
216
- > input[type="checkbox"], > input[type="radio"]{
217
- position: absolute;
218
- opacity: 0;
219
- pointer-events: none;
220
- &:checked ~ .check-label:before{
221
- color: $primary;
222
- }
223
- // disabled style
224
- &:disabled ~ .check-label{
225
- cursor: not-allowed;
226
- span, &:hover span,
227
- &:before, &:hover &:before{
228
- color: var(--gray-500);
229
- }
230
- }
231
- &:checked:disabled ~ .check-label{
232
- &:before, &:hover &:before{
233
- color: var(--gray-600);
234
- }
235
- }
236
- }
237
- > input[type="checkbox"] ~ .check-label:before{ content: "check_box_outline_blank"; }
238
- > input[type="radio"] ~ .check-label:before{ content: "radio_button_unchecked"; }
239
- > input[type="checkbox"]:checked ~ .check-label:before{ content: "check_box"; }
240
- > input[type="radio"]:checked ~ .check-label:before{ content: "radio_button_checked"; }
241
- }
242
- // checkbox / radio ------------------------------------------
243
-
244
- // star ------------------------------------------
245
- .check-star-group{
246
- > input[type="checkbox"], > input[type="radio"]{
247
- ~ .check-label:before{
248
- content: "star_border";
249
- font-size: 1.5em;
250
- }
251
- ~ .check-label:hover:before{
252
- color: $warning;
253
- }
254
- &:checked ~ .check-label:before{
255
- content: "star";
256
- color: $warning;
257
- }
258
- }
259
- }
260
- // star ------------------------------------------
261
-
262
-
263
- // switch ------------------------------------------
264
-
265
- :root{
266
- --switch-w: 24px;
267
- --switch-h: 12px;
268
- --switch-padding: 2px;
269
- --switch-ball-size: calc( var(--switch-h) - var(--switch-padding)*2);
270
-
271
- }
272
- .check-switch-group{
273
- // reset
274
- .check-label:before{ content: ""; }
275
- .check-label .switch-item{
276
- position: relative;
277
- display: inline-block;
278
- width: var(--switch-w);
279
- height: var(--switch-h);
280
- border-radius: var(--switch-h);
281
- background-color: var(--gray-500);
282
- vertical-align: middle;
283
- &, &:before{
284
- transition: $transition-base;
285
- }
286
- &:before{
287
- content: "";
288
- position: absolute;
289
- top: 0;
290
- left: var(--switch-padding);
291
- bottom: 0;
292
- margin: auto;
293
- @include size(var(--switch-ball-size));
294
- border-radius: 50%;
295
- background-color: $white;
296
- }
297
- }
298
- > input[type="checkbox"], > input[type="radio"]{
299
- // reset
300
- ~ .check-label:before{ content: ""; }
301
- &:checked ~ .check-label:before{ content: ""; }
302
-
303
- &:not(:disabled) ~ .check-label:hover .switch-item:before{
304
- will-change: left;
305
- }
306
-
307
- &:checked ~ .check-label .switch-item:before{
308
- left: calc( var(--switch-w) - var(--switch-padding) - var(--switch-ball-size));
309
- }
310
-
311
- // disabled style
312
- &:disabled ~ .check-label .switch-item{
313
- background-color: var(--gray-400);
314
- }
315
- &:checked:disabled ~ .check-label .switch-item{
316
- background-color: var(--gray-600);
317
- }
318
- }
319
- &-md{
320
- --switch-w: 30px;
321
- --switch-h: 15px;
322
- --switch-padding: 3px;
323
- --switch-ball-size: calc( var(--switch-h) - var(--switch-padding)*2);
324
- }
325
- &-lg{
326
- --switch-w: 36px;
327
- --switch-h: 18px;
328
- --switch-padding: 3px;
329
- --switch-ball-size: calc( var(--switch-h) - var(--switch-padding)*2);
330
- }
331
- &-with-description{
332
- .switch-item{
333
- margin-top: .35em;
334
- }
335
- .check-label{
336
- display: flex;
337
- }
338
- }
339
- &-display .check-label{
340
- cursor: auto;
341
- }
342
- }
343
- @each $color, $value in $colors {
344
- .check-switch-group.check-switch-group-#{$color}{
345
- &:hover .check-label .switch-item{
346
- background-color: rgba($value, .5);
347
- }
348
- > input[type="checkbox"], > input[type="radio"]{
349
- &:checked:not(:disabled) ~ .check-label .switch-item{
350
- background-color: $value;
351
- }
352
- }
353
- &.check-switch-group-display{
354
- pointer-events: none;
355
- }
356
- &.check-switch-group-display.active .check-label .switch-item{
357
- background-color: $value;
358
- &:before{
359
- left: calc( var(--switch-w) - var(--switch-padding) - var(--switch-ball-size));
360
- }
361
- }
362
- }
363
- }
364
-
365
- // badge 版本
366
- .check-label.badge{
367
- --bs-badge-padding-x: 1em;
368
- --bs-badge-padding-y: 0.5em;
369
- --bs-badge-font-size: var(--bs-body-font-size);
370
- --bs-badge-font-weight: --bs-body-font-weight;
371
- }
372
- .check-switch-group.check-switch-group{
373
- input:not(:checked) ~ .check-label.badge{
374
- background-color: var(--gray-100);
375
- border-color: var(--gray-300);
376
- span{
377
- color: var(--gray-500);
378
- }
379
- }
380
- input:not(:checked):disabled ~ .check-label.badge{
381
- &:hover{
382
- background-color: var(--gray-100);
383
- border-color: var(--gray-300);
384
- }
385
- &:hover span, span{
386
- color: var(--gray-400);
387
- }
388
- }
389
- input:checked ~ .check-label.badge{
390
- &:hover span, span{
391
- color: currentColor;
392
- }
393
- .switch-item{
394
- background-color: currentColor;
395
- }
396
- }
397
- }
398
- @each $color, $value in $colors {
399
- .check-switch-group.check-switch-group-#{$color}{
400
- input:not(:disabled):not(:checked) ~ .check-label.badge:hover{
401
- background-color: rgba($value, .05);
402
- border-color: rgba($value, .25);
403
- .switch-item{
404
- background-color: rgba($value, .5);
405
- }
406
- span{
407
- color: rgba($value, .75);
408
- }
409
- }
410
- }
411
- }
412
- // switch ------------------------------------------
413
-
414
-
415
-
416
-
417
- // table ------------------------------------------
418
- th, td{
419
- transition: $transition-base;
420
- }
421
- .table > .thead-default:not(caption) > * > *{
422
- font-size: $font-size-sm;
423
- background-color: var(--gray-200);
424
- letter-spacing: 0.5px;
425
- }
426
-
427
- // firefox 暫不支援
428
- .table tr:has(.dropdown-delete:hover){
429
- th:not([scope="col"]), td:not([scope="col"]){
430
- --bs-table-accent-bg: transparent;
431
- --bs-table-bg: transparent;
432
- background-color: $table-danger-bg;
433
- color: var(--bs-danger);
434
- box-shadow: none;
435
- }
436
- }
437
-
438
- .table .dropdown-menu{
439
- z-index: $zindex-sticky + 1;
440
- }
441
-
442
- // table ------------------------------------------
443
-
444
-
445
-
446
- // icon ------------------------------------------
447
- .text-with-icon > *{
448
- vertical-align: middle;
449
- }
450
-
451
- .material-icons{
452
- $icon-sizes: 14, 18, 24, 28, 32;
453
-
454
- font-size: 24px;
455
- @each $size in $icon-sizes{
456
- &.icon-#{$size} { font-size: #{$size}px; }
457
- }
458
- }
459
- // icon ------------------------------------------
460
-
461
-
462
- // button ------------------------------------------
463
- .btn > *{
464
- vertical-align: middle;
465
- }
466
-
467
- .btn-round-effect{
468
- position: relative;
469
- display: inline-flex;
470
- align-items: center;
471
- justify-content: center;
472
- @include size(2em);
473
- padding: 0;
474
- text-decoration: none;
475
- *{
476
- z-index: 2;
477
- }
478
- &:before{
479
- content: "";
480
- display: block;
481
- @include position-center();
482
- border-radius: 50%;
483
- background-color: var(--bs-link-color);
484
- z-index: 1;
485
- opacity: 0;
486
- transform: scale(0);
487
- transition: $transition-base;
488
- }
489
- &:hover:before{
490
- opacity: .1;
491
- transform: scale(1);
492
- }
493
- }
494
-
495
- .btn-link-light-bg {
496
- text-decoration: none;
497
- &:hover {
498
- color: var(--bs-btn-color);
499
- background-color: rgba(var(--bs-link-color-rgb), .1);
500
- }
501
- }
502
-
503
-
504
- @keyframes gradient-position {
505
- 0% {
506
- transform: translateX(0);
507
- }
508
- 50% {
509
- transform: translateX(-50%);
510
- }
511
- 100% {
512
- transform: translateX(0);
513
- }
514
- }
515
- .btn-gradient-effect{
516
- --bs-btn-color: #fff;
517
- --bs-btn-hover-color: #fff;
518
- --bs-btn-active-color: #fff;
519
-
520
- position: relative;
521
- overflow: hidden;
522
- border: 0;
523
-
524
- &:before{
525
- content: "";
526
- display: block;
527
- position: absolute;
528
- top: 0; left: 0;
529
- width: 200%; height: 100%;
530
- background: linear-gradient(110deg, $cyan 0%, $purple 50%, $cyan 100%);
531
- animation: gradient-position 3s ease-in-out infinite;
532
- animation-fill-mode: both;
533
- z-index: 1;
534
- transition: $transition-base;
535
- }
536
- &, &:hover, &:hover:active{
537
- background-color: $primary;
538
- }
539
- &:hover:before{
540
- opacity: .4;
541
- }
542
- &:focus{
543
- box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
544
- }
545
- > *{
546
- position: relative;
547
- z-index: 2;
548
- }
549
- }
550
- // button ------------------------------------------
551
-
552
-
553
- // input ------------------------------------------
554
- .form-group{
555
- > label, .form-label{
556
- margin-bottom: 0.25rem;
557
- color: var(--gray-500);
558
- font-size: $font-size-sm;
559
- font-weight: $font-weight-bold;
560
- }
561
- }
562
-
563
- .form-group-frame{
564
- padding: 1rem;
565
- border-bottom: $border-width solid $border-color;
566
- }
567
- // input ------------------------------------------
568
-
569
-
570
- // image ------------------------------------------
571
- .thumbnail-content{
572
- $thumbnail-sizes: 32, 50, 100, 150;
573
-
574
- @include size(50px);
575
- background-color: $white;
576
- background-position: 50% 50%;
577
- background-size: cover;
578
- border: $border-width solid var(--#{$prefix}border-color);
579
- border-radius: 50%;
580
- overflow: hidden;
581
- @each $size in $thumbnail-sizes{
582
- &.thumbnail-#{$size} { @include solid-size(#{$size}px); }
583
- }
584
- &.thumbnail-rwd{
585
- @include rwd-square(100%);
586
- }
587
- }
588
- // image ------------------------------------------
589
-
590
-
591
- // dropdown ------------------------------------------
592
- .dropdown-menu{
593
- box-shadow: $box-shadow;
594
- }
595
- .dropdown-delete{
596
- color: $danger;
597
- &:hover{
598
- --bs-dropdown-link-hover-bg: var(--bs-danger);
599
- background-color: $danger;
600
- }
601
- }
602
- .dropdown-menu{
603
- --scrollbar-width: 8px;
604
- --scrollbar-hover-color: rgba(var(--bs-link-color-rgb), 0.5);
605
- overflow: auto;
606
- overscroll-behavior: contain;
607
- @include scrollbar();
608
- }
609
- // dropdown ------------------------------------------
610
-
611
-
612
- // modal ------------------------------------------
613
- .modal{
614
- backdrop-filter: var(--backdrop-blur);
615
- }
616
-
617
- .modal-md{
618
- min-width: 650px;
619
- }
620
-
621
- .modal-long-content .overflow-y-auto{
622
- height: 75vh;
623
- }
624
- // modal ------------------------------------------
625
-
626
-
627
- // offcanvas ------------------------------------------
628
- .offcanvas-backdrop{
629
- background-color: rgba($offcanvas-backdrop-bg, $offcanvas-backdrop-opacity);
630
- &.show{
631
- backdrop-filter: var(--backdrop-blur);
632
- opacity: 1;
633
- }
634
- }
635
- .offcanvas{
636
- &-md-size{
637
- --bs-offcanvas-width: 550px;
638
- }
639
- &-lg-size{
640
- --bs-offcanvas-width: 800px;
641
- }
642
- &-xl-size{
643
- --bs-offcanvas-width: 1000px;
644
- }
645
- }
646
- // offcanvas ------------------------------------------
647
-
648
-
649
- // navbar ------------------------------------------
650
- $navbar-h: 60px;
651
- .navbar-main{
652
- &, .btn.btn-normal, .navbar-line-item {
653
- min-height: $navbar-h;
654
- }
655
- .btn.btn-normal{
656
- @include flex-center();
657
- border-radius: 0;
658
- color: var(--bs-nav-link-color);
659
- &:hover{
660
- color: var(--bs-link-color);
661
- background-color: $primary-bg-light;
662
- }
663
- }
664
- .btn-square{
665
- @include size($navbar-h);
666
- }
667
- }
668
- // navbar ------------------------------------------
669
-
670
-
671
- // 側邊的清單 ------------------------------------------
672
-
673
- $list-highlight-border-w: .4rem;
674
-
675
- @mixin list-group-active(){
676
- font-weight: $font-weight-medium;
677
- border-left-color: currentColor;
678
- --bs-list-group-active-color: var(--bs-link-color);
679
- --bs-list-group-active-bg: transparent;
680
- @include gradient-bg();
681
- }
682
-
683
- .list-group{
684
- overflow: hidden;
685
- &, > li{
686
- list-style-type: none !important;
687
- }
688
- > li{
689
- position: relative;
690
- }
691
- .material-icon-more{
692
- transition: $transition-base;
693
- }
694
- }
695
-
696
- // 一般選單 style
697
- $list-item-padding-x: 1rem;
698
-
699
- .list-group-aside{
700
- border-radius: 0;
701
- .list-group-item{
702
- display: flex;
703
- align-items: center;
704
- padding: .8rem $list-item-padding-x;
705
- border-right: 0;
706
- border-color: transparent;
707
- border-left: $list-highlight-border-w solid transparent;
708
- background-color: var(--bs-body-bg);
709
- cursor: pointer;
710
- transition: $transition-base;
711
- &:before{ content: ""; }
712
- &.active{
713
- @include list-group-active();
714
- }
715
- &:not(.active):hover{
716
- border-top-color: var(--bs-body-bg);
717
- border-bottom-color: rgba(var(--bs-link-color-rgb), .1);
718
- border-left-color: $primary-sub-highlight;
719
- --bs-list-group-action-hover-color: rgba(var(--bs-link-color-rgb), .8);
720
- --bs-list-group-action-hover-bg: transparent;
721
- @include gradient-bg-hover-to-show(.7);
722
- }
723
- &:hover .material-icon-more{
724
- color: var(--bs-link-color);
725
- }
726
- }
727
- }
728
-
729
- // 子選單 style
730
- .child-body, .child-container{
731
- width: 100%;
732
- }
733
- .child-body{
734
- background: var(--gray-100);
735
- }
736
- .child-container{
737
- border-left: $list-highlight-border-w solid var(--gray-400);
738
- }
739
- .child-list-head{
740
- padding: .25rem $list-item-padding-x;
741
- color: var(--gray-500);
742
- background-color: var(--gray-200);
743
- font-weight: $font-weight-bold;
744
- border-bottom: $border-width solid var(--gray-400);
745
- }
746
- a.child-list-item{
747
- position: relative;
748
- display: block;
749
- padding: .5rem $list-item-padding-x;
750
- font-size: $font-size-sm;
751
-
752
- &:hover{
753
- color: var(--bs-link-color);
754
- }
755
- &.active{
756
- color: var(--bs-link-color);
757
- @include gradient-bg();
758
- }
759
- &.disabled, &:disabled{
760
- color: var(--bs-list-group-disabled-color);
761
- pointer-events: none;
762
- }
763
- @include gradient-bg-hover-to-show(.7);
764
- }
765
-
766
-
767
- // 子選單開合
768
- // https://stackoverflow.com/questions/3508605/how-can-i-transition-height-0-to-height-auto-using-css
769
- $list-toogle-speed: .35s;
770
- $list-toogle-in-background: $list-toogle-speed linear;
771
-
772
- .list-group-haschild:hover ~ .child-body{
773
- &:after{ will-change: height, max-height; }
774
- > .child-container { will-change: max-height, margin-bottom; }
775
- }
776
-
777
- .child-body{
778
- position: relative;
779
- display: flex;
780
- overflow: hidden;
781
- &:after { content: ''; }
782
- // 關閉 -----------------
783
- &:after{
784
- height: 0;
785
- max-height: 50px;
786
- transition: height $list-toogle-in-background;
787
- }
788
- > .child-container {
789
- margin-bottom: -2000px;
790
- visibility: hidden;
791
- max-height: 0;
792
- transition: margin-bottom $list-toogle-speed cubic-bezier(1, 0, 1, 1),
793
- visibility 0s $list-toogle-speed,
794
- max-height 0s $list-toogle-speed;
795
- }
796
- // 關閉 -----------------
797
- }
798
-
799
- .list-group-haschild-input:checked{
800
- ~ .list-group-item{
801
- @include list-group-active();
802
- .material-icon-more{
803
- transform: rotate(-180deg);
804
- }
805
- }
806
- ~ .child-body{
807
- // 打開 -----------------
808
- &:after {
809
- height: 50px;
810
- transition: height $list-toogle-in-background,
811
- max-height 0s $list-toogle-in-background;
812
- max-height: 0px;
813
- }
814
- > .child-container{
815
- transition: margin-bottom $list-toogle-speed cubic-bezier(0, 0, 0, 1);
816
- margin-bottom: 0;
817
- visibility: visible;
818
- max-height: 1000000px;
819
- }
820
- // 打開 -----------------
821
- }
822
- }
823
-
824
- // 側邊的清單 ------------------------------------------
825
-
826
-
827
-
828
- // navbar ------------------------------------------
829
- .nav-link.active{
830
- font-weight: $font-weight-bold;
831
- }
832
- // navbar ------------------------------------------
833
-
834
-
835
- // 有底線的 tab bar ------------------------------------------
836
- .navbar-line{
837
- &:hover .navbar-line-item{
838
- &:before { will-change: width, left; }
839
- ~ .navbar-line-item:before{ will-change: left; }
840
- }
841
- // LG 版本 (底線較粗)
842
- &.navbar-line-lg .navbar-line-item:before{
843
- border-bottom-width: 4px;
844
- }
845
- }
846
-
847
- a.navbar-line-item{
848
- --bs-link-color-rgb: 100, 122, 241;
849
- }
850
- .navbar-line-item{
851
- position: relative;
852
- @include flex-center();
853
- --bs-navbar-nav-link-padding-x: 1.5rem;
854
- color: var(--bs-nav-link-color);
855
- &:before{
856
- content: "";
857
- position: absolute;
858
- top: 0;
859
- left: 100%;
860
- width: 0;
861
- height: 100%;
862
- border-bottom: 2px solid var(--bs-link-color);
863
- transition: $transition-base;
864
- pointer-events: none;
865
- z-index: 1;
866
- }
867
- &:hover{
868
- background: $primary-bg-light;
869
- &:before {
870
- width: 100%;
871
- left: 0;
872
- }
873
- ~ .navbar-line-item:before{
874
- left: 0;
875
- }
876
- }
877
- &:not(.active):hover:before{
878
- border-color: $primary-sub-highlight;
879
- }
880
- &.active:before{
881
- width: 100%;
882
- left: 0;
883
- }
884
- }
885
- // dropdown 版本
886
- .navbar-line-item.dropdown{
887
- padding: 0;
888
- padding-left: 0 !important;
889
- padding-right: 0 !important;
890
- // (firefox 暫不支援)
891
- &:has(.dropdown-toggle[aria-expanded="true"]){
892
- background: $primary-bg-light;
893
- &:before{
894
- width: 100%;
895
- left: 0;
896
- border-bottom-color: $primary-sub-highlight;
897
- }
898
- }
899
- &:not(.active) .dropdown-link{
900
- color: var(--bs-nav-link-color);
901
- }
902
- .dropdown-link{
903
- @include flex-center();
904
- height: 100%;
905
- padding: var(--bs-nav-link-padding-y) var(--bs-navbar-nav-link-padding-x);
906
- }
907
- .dropdown-toggle[aria-expanded="true"]{
908
- color: $primary;
909
- }
910
- }
911
-
912
-
913
- .navbar[data-bs-theme="dark"]{
914
- --dark-theme-primary: #bec9ff;
915
- .navbar-line-item.dropdown:not(.active) .dropdown-link{
916
- color: var(--dark-theme-primary);
917
- }
918
- .navbar-nav .show > .nav-link, .navbar-nav .nav-link.active{
919
- &, a{
920
- color: $white;
921
- }
922
- }
923
- .navbar-line-item:before{
924
- border-bottom-color: var(--dark-theme-primary);
925
- }
926
- .navbar-line-item.dropdown:not(.active) .dropdown-link,
927
- .navbar-line-item:before{
928
- opacity: .9;
929
- }
930
- }
931
- // 有底線的 tab bar ------------------------------------------
932
-
933
-
934
-
935
- // 固定寬度 ------------------------------------------
936
- .w-33{
937
- width: 33.33%;
938
- }
939
- .w-66{
940
- width: 66.66%;
941
- }
942
- @for $i from 1 through 25 {
943
- .w-#{$i}rem {
944
- width: #{$i}rem;
945
- }
946
- }
947
-
948
- // 固定寬度 ------------------------------------------
949
-
950
-
951
-
952
- // 無內容物 UI ------------------------------------------
953
- .no-content{
954
- padding-top: 10rem;
955
- .content-img > .material-icons, p{
956
- opacity: .7;
957
- }
958
- .content-img > .material-icons{
959
- font-size: 6rem;
960
- margin-bottom: 0.5rem;
961
- opacity: .5;
962
- }
963
- p{
964
- font-size: 1.25rem;
965
- }
966
- }
967
- // 無內容物 UI ------------------------------------------
968
-
969
-
970
-
971
- // 暫定:螢幕寬度小於 991px (含) 不可使用 ------------------------------------------
972
- .mobile-forbidden{
973
- display: none;
974
- }
975
- @media only screen and (max-width: 991px) {
976
- body{
977
- overflow: hidden;
978
- }
979
- .mobile-forbidden{
980
- position: fixed;
981
- top: 0;
982
- left: 0;
983
- right: 0;
984
- bottom: 0;
985
- margin: auto;
986
- @include flex-center();
987
- flex-direction: column;
988
- padding: 2rem;
989
- font-size: $font-size-lg;
990
- text-align: center;
991
- color: var(--gray-500);
992
- background: $white $gradient-blue-light;
993
- z-index: $zindex-max;
994
- img {
995
- width: 20rem;
996
- }
997
- }
998
- }
999
- // 暫定:螢幕寬度小於 991px (含) 不可使用 ------------------------------------------
1000
-
1001
-
1002
-
1003
- // sweet alert ------------------------------------------
1004
- .swal2-container{
1005
- &.swal2-backdrop-show, &.swal2-noanimation{
1006
- backdrop-filter: var(--backdrop-blur);
1007
- }
1008
- }
1009
-
1010
- div:where(.swal2-container){
1011
- .swal2-html-container{
1012
- font-size: 1rem !important;
1013
- color: var(--bs-body-color) !important;
1014
- }
1015
- h2:where(.swal2-title){
1016
- font-size: 1.5rem !important;
1017
- color: var(--bs-emphasis-color) !important;
1018
- }
1019
- .swal2-actions{
1020
- flex-direction: row-reverse;
1021
- width: 100%;
1022
- }
1023
- button:where(.swal2-styled){
1024
- margin-left: .5rem !important;
1025
- margin-right: .5rem !important;
1026
- }
1027
-
1028
- button:where(.swal2-styled).swal2-cancel{
1029
- background-color: $secondary !important;
1030
- }
1031
- }
1
+ // ====================================
2
+ // Plugin
3
+ // ====================================
4
+
5
+ // Custom Bootstrap
6
+ @import "../../../../bootstrap/scss/functions";
7
+ @import "../Settings/bs-variables";
8
+ @import "../../../../bootstrap/scss/bootstrap.scss";
9
+
10
+
11
+ // ====================================
12
+ // Helpers
13
+ // ====================================
14
+
15
+ // Mixins
16
+ @import "../Settings/Mixins";
17
+
18
+
19
+ // ====================================
20
+ // Custom Style
21
+ // ====================================
22
+
23
+ @import "../Settings/color-mode";
24
+ @import "../Settings/custom-variables";
25
+
26
+
27
+ @mixin gradient-bg(){
28
+ &:before{
29
+ content: "";
30
+ display: block;
31
+ @include position-center();
32
+ z-index: 0;
33
+ background: $gradient-blue-light;
34
+ pointer-events: none;
35
+ transition: $transition-base;
36
+ }
37
+ }
38
+
39
+ @mixin gradient-bg-hover-to-show($opacity: 1){
40
+ @include gradient-bg();
41
+ &:before{ opacity: 0; }
42
+ &:hover:before{ opacity: $opacity; }
43
+ }
44
+
45
+ // general ------------------------------------------
46
+ :root{
47
+ --backdrop-blur: blur(2px);
48
+
49
+ // ====================================
50
+ // scrollbar樣式
51
+ // ====================================
52
+ --scrollbar-width: 10px;
53
+ }
54
+
55
+ [v-cloak]{
56
+ display: none !important;
57
+ }
58
+
59
+ html,
60
+ .overflow-auto, .overflow-scroll,
61
+ .overflow-y-auto, .overflow-y-scroll,
62
+ .offcanvas-body, textarea{
63
+ @include scrollbar();
64
+ transition: $transition-base;
65
+ }
66
+
67
+ .overflow-x-auto, .overflow-x-scroll, .scrollbar-sm, .table-responsive{
68
+ @include scrollbar();
69
+ --scrollbar-width: 6px;
70
+ overflow-x: auto;
71
+ -webkit-overflow-scrolling: touch;
72
+ }
73
+
74
+ .scrollbar-gutter-stable{
75
+ // Safari 暫不支援
76
+ scrollbar-gutter: stable;
77
+ }
78
+
79
+ body{
80
+ background-color: var(--gray-200);
81
+ --maz-color-primary: var(--bs-primary);
82
+ --maz-color-secondary: var(--bs-secondary);
83
+ --maz-color-info: var(--bs-info);
84
+ --maz-color-success: var(--bs-success);
85
+ --maz-color-warning: var(--bs-warning);
86
+ --maz-color-danger: var(--bs-danger);
87
+ --maz-color-bg: var(--bs-body-bg);
88
+ --maz-color-text: var(--bs-body-color);
89
+ --maz-color-muted: var(--bs-secondary-color);
90
+ }
91
+
92
+ ul, ol{
93
+ &.list-reset{
94
+ list-style-type: none;
95
+ padding-left: 0;
96
+ }
97
+ }
98
+ // general ------------------------------------------
99
+
100
+
101
+ // text / link ------------------------------------------
102
+ a{
103
+ text-decoration: none;
104
+ // 如果需要底線使用 <u></u> tag
105
+ transition: $transition-base;
106
+ &.a-reset-color{
107
+ color: inherit;
108
+ }
109
+ &.a-hover-gradient{
110
+ position: relative;
111
+ @include gradient-bg-hover-to-show();
112
+ }
113
+ }
114
+
115
+ .text-link{
116
+ color: var(--bs-link-color);
117
+ &:hover{
118
+ color: var(--bs-link-hover-color);
119
+ }
120
+ }
121
+
122
+ .text-pre-wrap{
123
+ white-space: pre-wrap;
124
+ }
125
+
126
+ .fs-min{
127
+ font-size: 12px;
128
+ }
129
+
130
+ .text-overflow{
131
+ @include text-overflow();
132
+ }
133
+
134
+ @for $i from 1 through 5 {
135
+ .text-line-clamp-#{$i} {
136
+ @include text-line-clamp(#{$i});
137
+ }
138
+ }
139
+
140
+ @for $i from 1 through 5 {
141
+ .letter-spacing-#{$i} {
142
+ letter-spacing: #{$i}px;
143
+ }
144
+ }
145
+
146
+ // text / link ------------------------------------------
147
+
148
+
149
+ // border ------------------------------------------
150
+ .hover-border{
151
+ transition: $transition-base;
152
+ &:hover{
153
+ box-shadow: $focus-ring-box-shadow;
154
+ }
155
+ }
156
+ .active-border{
157
+ box-shadow: $focus-ring-box-shadow;
158
+ }
159
+ // border ------------------------------------------
160
+
161
+
162
+ // badge outline ------------------------------------------
163
+
164
+ @each $color, $value in $colors {
165
+ .badge-outline-#{$color}{
166
+ color: $value;
167
+ border: $border-width solid rgba($value, .5);
168
+ background-color: rgba($value, .1);
169
+ }
170
+ }
171
+
172
+ // badge outline ------------------------------------------
173
+
174
+
175
+ // input ------------------------------------------
176
+ .form-control{
177
+ caret-color: $primary;
178
+ }
179
+ // input ------------------------------------------
180
+
181
+
182
+ // checkbox / radio ------------------------------------------
183
+
184
+ .check-label{
185
+ cursor: pointer;
186
+ &, &:before, span{
187
+ vertical-align: middle;
188
+ transition: $transition-base;
189
+ }
190
+ &:before{
191
+ content: "check_box_outline_blank";
192
+ display: inline-block;
193
+ margin-right: .1em;
194
+ color: var(--gray-500);
195
+ font-family: 'Material Icons';
196
+ font-size: 120%;
197
+ line-height: inherit;
198
+ white-space: nowrap;
199
+ -webkit-font-feature-settings: 'liga';
200
+ -webkit-font-smoothing: antialiased;
201
+ }
202
+ &:not(.badge):hover{
203
+ &, &:before, span{
204
+ color: $primary;
205
+ }
206
+ }
207
+ }
208
+
209
+ .check-group{
210
+ position: relative;
211
+ display: inline-block;
212
+ vertical-align: middle;
213
+ &:not(:last-child){
214
+ margin-right: 1em;
215
+ }
216
+ > input[type="checkbox"], > input[type="radio"]{
217
+ position: absolute;
218
+ opacity: 0;
219
+ pointer-events: none;
220
+ &:checked ~ .check-label:before{
221
+ color: $primary;
222
+ }
223
+ // disabled style
224
+ &:disabled ~ .check-label{
225
+ cursor: not-allowed;
226
+ span, &:hover span,
227
+ &:before, &:hover &:before{
228
+ color: var(--gray-500);
229
+ }
230
+ }
231
+ &:checked:disabled ~ .check-label{
232
+ &:before, &:hover &:before{
233
+ color: var(--gray-600);
234
+ }
235
+ }
236
+ }
237
+ > input[type="checkbox"] ~ .check-label:before{ content: "check_box_outline_blank"; }
238
+ > input[type="radio"] ~ .check-label:before{ content: "radio_button_unchecked"; }
239
+ > input[type="checkbox"]:checked ~ .check-label:before{ content: "check_box"; }
240
+ > input[type="radio"]:checked ~ .check-label:before{ content: "radio_button_checked"; }
241
+ }
242
+ // checkbox / radio ------------------------------------------
243
+
244
+ // star ------------------------------------------
245
+ .check-star-group{
246
+ > input[type="checkbox"], > input[type="radio"]{
247
+ ~ .check-label:before{
248
+ content: "star_border";
249
+ font-size: 1.5em;
250
+ }
251
+ ~ .check-label:hover:before{
252
+ color: $warning;
253
+ }
254
+ &:checked ~ .check-label:before{
255
+ content: "star";
256
+ color: $warning;
257
+ }
258
+ }
259
+ }
260
+ // star ------------------------------------------
261
+
262
+
263
+ // switch ------------------------------------------
264
+
265
+ :root{
266
+ --switch-w: 24px;
267
+ --switch-h: 12px;
268
+ --switch-padding: 2px;
269
+ --switch-ball-size: calc( var(--switch-h) - var(--switch-padding)*2);
270
+
271
+ }
272
+ .check-switch-group{
273
+ // reset
274
+ .check-label:before{ content: ""; }
275
+ .check-label .switch-item{
276
+ position: relative;
277
+ display: inline-block;
278
+ width: var(--switch-w);
279
+ height: var(--switch-h);
280
+ border-radius: var(--switch-h);
281
+ background-color: var(--gray-500);
282
+ vertical-align: middle;
283
+ &, &:before{
284
+ transition: $transition-base;
285
+ }
286
+ &:before{
287
+ content: "";
288
+ position: absolute;
289
+ top: 0;
290
+ left: var(--switch-padding);
291
+ bottom: 0;
292
+ margin: auto;
293
+ @include size(var(--switch-ball-size));
294
+ border-radius: 50%;
295
+ background-color: $white;
296
+ }
297
+ }
298
+ > input[type="checkbox"], > input[type="radio"]{
299
+ // reset
300
+ ~ .check-label:before{ content: ""; }
301
+ &:checked ~ .check-label:before{ content: ""; }
302
+
303
+ &:not(:disabled) ~ .check-label:hover .switch-item:before{
304
+ will-change: left;
305
+ }
306
+
307
+ &:checked ~ .check-label .switch-item:before{
308
+ left: calc( var(--switch-w) - var(--switch-padding) - var(--switch-ball-size));
309
+ }
310
+
311
+ // disabled style
312
+ &:disabled ~ .check-label .switch-item{
313
+ background-color: var(--gray-400);
314
+ }
315
+ &:checked:disabled ~ .check-label .switch-item{
316
+ background-color: var(--gray-600);
317
+ }
318
+ }
319
+ &-md{
320
+ --switch-w: 30px;
321
+ --switch-h: 15px;
322
+ --switch-padding: 3px;
323
+ --switch-ball-size: calc( var(--switch-h) - var(--switch-padding)*2);
324
+ }
325
+ &-lg{
326
+ --switch-w: 36px;
327
+ --switch-h: 18px;
328
+ --switch-padding: 3px;
329
+ --switch-ball-size: calc( var(--switch-h) - var(--switch-padding)*2);
330
+ }
331
+ &-with-description{
332
+ .switch-item{
333
+ margin-top: .35em;
334
+ }
335
+ .check-label{
336
+ display: flex;
337
+ }
338
+ }
339
+ &-display .check-label{
340
+ cursor: auto;
341
+ }
342
+ }
343
+ @each $color, $value in $colors {
344
+ .check-switch-group.check-switch-group-#{$color}{
345
+ &:hover .check-label .switch-item{
346
+ background-color: rgba($value, .5);
347
+ }
348
+ > input[type="checkbox"], > input[type="radio"]{
349
+ &:checked:not(:disabled) ~ .check-label .switch-item{
350
+ background-color: $value;
351
+ }
352
+ }
353
+ &.check-switch-group-display{
354
+ pointer-events: none;
355
+ }
356
+ &.check-switch-group-display.active .check-label .switch-item{
357
+ background-color: $value;
358
+ &:before{
359
+ left: calc( var(--switch-w) - var(--switch-padding) - var(--switch-ball-size));
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ // badge 版本
366
+ .check-label.badge{
367
+ --bs-badge-padding-x: 1em;
368
+ --bs-badge-padding-y: 0.5em;
369
+ --bs-badge-font-size: var(--bs-body-font-size);
370
+ --bs-badge-font-weight: --bs-body-font-weight;
371
+ }
372
+ .check-switch-group.check-switch-group{
373
+ input:not(:checked) ~ .check-label.badge{
374
+ background-color: var(--gray-100);
375
+ border-color: var(--gray-300);
376
+ span{
377
+ color: var(--gray-500);
378
+ }
379
+ }
380
+ input:not(:checked):disabled ~ .check-label.badge{
381
+ &:hover{
382
+ background-color: var(--gray-100);
383
+ border-color: var(--gray-300);
384
+ }
385
+ &:hover span, span{
386
+ color: var(--gray-400);
387
+ }
388
+ }
389
+ input:checked ~ .check-label.badge{
390
+ &:hover span, span{
391
+ color: currentColor;
392
+ }
393
+ .switch-item{
394
+ background-color: currentColor;
395
+ }
396
+ }
397
+ }
398
+ @each $color, $value in $colors {
399
+ .check-switch-group.check-switch-group-#{$color}{
400
+ input:not(:disabled):not(:checked) ~ .check-label.badge:hover{
401
+ background-color: rgba($value, .05);
402
+ border-color: rgba($value, .25);
403
+ .switch-item{
404
+ background-color: rgba($value, .5);
405
+ }
406
+ span{
407
+ color: rgba($value, .75);
408
+ }
409
+ }
410
+ }
411
+ }
412
+ // switch ------------------------------------------
413
+
414
+
415
+
416
+
417
+ // table ------------------------------------------
418
+ th, td{
419
+ transition: $transition-base;
420
+ }
421
+ .table > .thead-default:not(caption) > * > *{
422
+ font-size: $font-size-sm;
423
+ background-color: var(--gray-200);
424
+ letter-spacing: 0.5px;
425
+ }
426
+
427
+ // firefox 暫不支援
428
+ .table tr:has(.dropdown-delete:hover){
429
+ th:not([scope="col"]), td:not([scope="col"]){
430
+ --bs-table-accent-bg: transparent;
431
+ --bs-table-bg: transparent;
432
+ background-color: $table-danger-bg;
433
+ color: var(--bs-danger);
434
+ box-shadow: none;
435
+ }
436
+ }
437
+
438
+ .table .dropdown-menu{
439
+ z-index: $zindex-sticky + 1;
440
+ }
441
+
442
+ // table ------------------------------------------
443
+
444
+
445
+
446
+ // icon ------------------------------------------
447
+ .text-with-icon > *{
448
+ vertical-align: middle;
449
+ }
450
+
451
+ .material-icons{
452
+ $icon-sizes: 14, 18, 24, 28, 32;
453
+
454
+ font-size: 24px;
455
+ @each $size in $icon-sizes{
456
+ &.icon-#{$size} { font-size: #{$size}px; }
457
+ }
458
+ }
459
+ // icon ------------------------------------------
460
+
461
+
462
+ // button ------------------------------------------
463
+ .btn > *{
464
+ vertical-align: middle;
465
+ }
466
+
467
+ .btn-round-effect{
468
+ position: relative;
469
+ display: inline-flex;
470
+ align-items: center;
471
+ justify-content: center;
472
+ @include size(2em);
473
+ padding: 0;
474
+ text-decoration: none;
475
+ *{
476
+ z-index: 2;
477
+ }
478
+ &:before{
479
+ content: "";
480
+ display: block;
481
+ @include position-center();
482
+ border-radius: 50%;
483
+ background-color: var(--bs-link-color);
484
+ z-index: 1;
485
+ opacity: 0;
486
+ transform: scale(0);
487
+ transition: $transition-base;
488
+ }
489
+ &:hover:before{
490
+ opacity: .1;
491
+ transform: scale(1);
492
+ }
493
+ }
494
+
495
+ .btn-link-light-bg {
496
+ text-decoration: none;
497
+ &:hover {
498
+ color: var(--bs-btn-color);
499
+ background-color: rgba(var(--bs-link-color-rgb), .1);
500
+ }
501
+ }
502
+
503
+
504
+ @keyframes gradient-position {
505
+ 0% {
506
+ transform: translateX(0);
507
+ }
508
+ 50% {
509
+ transform: translateX(-50%);
510
+ }
511
+ 100% {
512
+ transform: translateX(0);
513
+ }
514
+ }
515
+ .btn-gradient-effect{
516
+ --bs-btn-color: #fff;
517
+ --bs-btn-hover-color: #fff;
518
+ --bs-btn-active-color: #fff;
519
+
520
+ position: relative;
521
+ overflow: hidden;
522
+ border: 0;
523
+
524
+ &:before{
525
+ content: "";
526
+ display: block;
527
+ position: absolute;
528
+ top: 0; left: 0;
529
+ width: 200%; height: 100%;
530
+ background: linear-gradient(110deg, $cyan 0%, $purple 50%, $cyan 100%);
531
+ animation: gradient-position 3s ease-in-out infinite;
532
+ animation-fill-mode: both;
533
+ z-index: 1;
534
+ transition: $transition-base;
535
+ }
536
+ &, &:hover, &:hover:active{
537
+ background-color: $primary;
538
+ }
539
+ &:hover:before{
540
+ opacity: .4;
541
+ }
542
+ &:focus{
543
+ box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
544
+ }
545
+ > *{
546
+ position: relative;
547
+ z-index: 2;
548
+ }
549
+ }
550
+ // button ------------------------------------------
551
+
552
+
553
+ // input ------------------------------------------
554
+ .form-group{
555
+ > label, .form-label{
556
+ margin-bottom: 0.25rem;
557
+ color: var(--gray-500);
558
+ font-size: $font-size-sm;
559
+ font-weight: $font-weight-bold;
560
+ }
561
+ }
562
+
563
+ .form-group-frame{
564
+ padding: 1rem;
565
+ border-bottom: $border-width solid $border-color;
566
+ }
567
+ // input ------------------------------------------
568
+
569
+
570
+ // image ------------------------------------------
571
+ .thumbnail-content{
572
+ $thumbnail-sizes: 32, 50, 100, 150;
573
+
574
+ @include size(50px);
575
+ background-color: $white;
576
+ background-position: 50% 50%;
577
+ background-size: cover;
578
+ border: $border-width solid var(--#{$prefix}border-color);
579
+ border-radius: 50%;
580
+ overflow: hidden;
581
+ @each $size in $thumbnail-sizes{
582
+ &.thumbnail-#{$size} { @include solid-size(#{$size}px); }
583
+ }
584
+ &.thumbnail-rwd{
585
+ @include rwd-square(100%);
586
+ }
587
+ }
588
+ // image ------------------------------------------
589
+
590
+
591
+ // dropdown ------------------------------------------
592
+ .dropdown-menu{
593
+ box-shadow: $box-shadow;
594
+ }
595
+ .dropdown-delete{
596
+ color: $danger;
597
+ &:hover{
598
+ --bs-dropdown-link-hover-bg: var(--bs-danger);
599
+ background-color: $danger;
600
+ }
601
+ }
602
+ .dropdown-menu{
603
+ --scrollbar-width: 8px;
604
+ --scrollbar-hover-color: rgba(var(--bs-link-color-rgb), 0.5);
605
+ overflow: auto;
606
+ overscroll-behavior: contain;
607
+ @include scrollbar();
608
+ }
609
+ // dropdown ------------------------------------------
610
+
611
+
612
+ // modal ------------------------------------------
613
+ .modal{
614
+ backdrop-filter: var(--backdrop-blur);
615
+ }
616
+
617
+ .modal-md{
618
+ min-width: 650px;
619
+ }
620
+
621
+ .modal-long-content .overflow-y-auto{
622
+ height: 75vh;
623
+ }
624
+ // modal ------------------------------------------
625
+
626
+
627
+ // offcanvas ------------------------------------------
628
+ .offcanvas-backdrop{
629
+ background-color: rgba($offcanvas-backdrop-bg, $offcanvas-backdrop-opacity);
630
+ &.show{
631
+ backdrop-filter: var(--backdrop-blur);
632
+ opacity: 1;
633
+ }
634
+ }
635
+ .offcanvas{
636
+ &-md-size{
637
+ --bs-offcanvas-width: 550px;
638
+ }
639
+ &-lg-size{
640
+ --bs-offcanvas-width: 800px;
641
+ }
642
+ &-xl-size{
643
+ --bs-offcanvas-width: 1000px;
644
+ }
645
+ }
646
+ // offcanvas ------------------------------------------
647
+
648
+
649
+ // navbar ------------------------------------------
650
+ $navbar-h: 60px;
651
+ .navbar-main{
652
+ &, .btn.btn-normal, .navbar-line-item {
653
+ min-height: $navbar-h;
654
+ }
655
+ .btn.btn-normal{
656
+ @include flex-center();
657
+ border-radius: 0;
658
+ color: var(--bs-nav-link-color);
659
+ &:hover{
660
+ color: var(--bs-link-color);
661
+ background-color: $primary-bg-light;
662
+ }
663
+ }
664
+ .btn-square{
665
+ @include size($navbar-h);
666
+ }
667
+ }
668
+ // navbar ------------------------------------------
669
+
670
+
671
+ // 側邊的清單 ------------------------------------------
672
+
673
+ $list-highlight-border-w: .4rem;
674
+
675
+ @mixin list-group-active(){
676
+ font-weight: $font-weight-medium;
677
+ border-left-color: currentColor;
678
+ --bs-list-group-active-color: var(--bs-link-color);
679
+ --bs-list-group-active-bg: transparent;
680
+ @include gradient-bg();
681
+ }
682
+
683
+ .list-group{
684
+ overflow: hidden;
685
+ &, > li{
686
+ list-style-type: none !important;
687
+ }
688
+ > li{
689
+ position: relative;
690
+ }
691
+ .material-icon-more{
692
+ transition: $transition-base;
693
+ }
694
+ }
695
+
696
+ // 一般選單 style
697
+ $list-item-padding-x: 1rem;
698
+
699
+ .list-group-aside{
700
+ border-radius: 0;
701
+ .list-group-item{
702
+ display: flex;
703
+ align-items: center;
704
+ padding: .8rem $list-item-padding-x;
705
+ border-right: 0;
706
+ border-color: transparent;
707
+ border-left: $list-highlight-border-w solid transparent;
708
+ background-color: var(--bs-body-bg);
709
+ cursor: pointer;
710
+ transition: $transition-base;
711
+ &:before{ content: ""; }
712
+ &.active{
713
+ @include list-group-active();
714
+ }
715
+ &:not(.active):hover{
716
+ border-top-color: var(--bs-body-bg);
717
+ border-bottom-color: rgba(var(--bs-link-color-rgb), .1);
718
+ border-left-color: $primary-sub-highlight;
719
+ --bs-list-group-action-hover-color: rgba(var(--bs-link-color-rgb), .8);
720
+ --bs-list-group-action-hover-bg: transparent;
721
+ @include gradient-bg-hover-to-show(.7);
722
+ }
723
+ &:hover .material-icon-more{
724
+ color: var(--bs-link-color);
725
+ }
726
+ }
727
+ }
728
+
729
+ // 子選單 style
730
+ .child-body, .child-container{
731
+ width: 100%;
732
+ }
733
+ .child-body{
734
+ background: var(--gray-100);
735
+ }
736
+ .child-container{
737
+ border-left: $list-highlight-border-w solid var(--gray-400);
738
+ }
739
+ .child-list-head{
740
+ padding: .25rem $list-item-padding-x;
741
+ color: var(--gray-500);
742
+ background-color: var(--gray-200);
743
+ font-weight: $font-weight-bold;
744
+ border-bottom: $border-width solid var(--gray-400);
745
+ }
746
+ a.child-list-item{
747
+ position: relative;
748
+ display: block;
749
+ padding: .5rem $list-item-padding-x;
750
+ font-size: $font-size-sm;
751
+
752
+ &:hover{
753
+ color: var(--bs-link-color);
754
+ }
755
+ &.active{
756
+ color: var(--bs-link-color);
757
+ @include gradient-bg();
758
+ }
759
+ &.disabled, &:disabled{
760
+ color: var(--bs-list-group-disabled-color);
761
+ pointer-events: none;
762
+ }
763
+ @include gradient-bg-hover-to-show(.7);
764
+ }
765
+
766
+
767
+ // 子選單開合
768
+ // https://stackoverflow.com/questions/3508605/how-can-i-transition-height-0-to-height-auto-using-css
769
+ $list-toogle-speed: .35s;
770
+ $list-toogle-in-background: $list-toogle-speed linear;
771
+
772
+ .list-group-haschild:hover ~ .child-body{
773
+ &:after{ will-change: height, max-height; }
774
+ > .child-container { will-change: max-height, margin-bottom; }
775
+ }
776
+
777
+ .child-body{
778
+ position: relative;
779
+ display: flex;
780
+ overflow: hidden;
781
+ &:after { content: ''; }
782
+ // 關閉 -----------------
783
+ &:after{
784
+ height: 0;
785
+ max-height: 50px;
786
+ transition: height $list-toogle-in-background;
787
+ }
788
+ > .child-container {
789
+ margin-bottom: -2000px;
790
+ visibility: hidden;
791
+ max-height: 0;
792
+ transition: margin-bottom $list-toogle-speed cubic-bezier(1, 0, 1, 1),
793
+ visibility 0s $list-toogle-speed,
794
+ max-height 0s $list-toogle-speed;
795
+ }
796
+ // 關閉 -----------------
797
+ }
798
+
799
+ .list-group-haschild-input:checked{
800
+ ~ .list-group-item{
801
+ @include list-group-active();
802
+ .material-icon-more{
803
+ transform: rotate(-180deg);
804
+ }
805
+ }
806
+ ~ .child-body{
807
+ // 打開 -----------------
808
+ &:after {
809
+ height: 50px;
810
+ transition: height $list-toogle-in-background,
811
+ max-height 0s $list-toogle-in-background;
812
+ max-height: 0px;
813
+ }
814
+ > .child-container{
815
+ transition: margin-bottom $list-toogle-speed cubic-bezier(0, 0, 0, 1);
816
+ margin-bottom: 0;
817
+ visibility: visible;
818
+ max-height: 1000000px;
819
+ }
820
+ // 打開 -----------------
821
+ }
822
+ }
823
+
824
+ // 側邊的清單 ------------------------------------------
825
+
826
+
827
+
828
+ // navbar ------------------------------------------
829
+ .nav-link.active{
830
+ font-weight: $font-weight-bold;
831
+ }
832
+ // navbar ------------------------------------------
833
+
834
+
835
+ // 有底線的 tab bar ------------------------------------------
836
+ .navbar-line{
837
+ &:hover .navbar-line-item{
838
+ &:before { will-change: width, left; }
839
+ ~ .navbar-line-item:before{ will-change: left; }
840
+ }
841
+ // LG 版本 (底線較粗)
842
+ &.navbar-line-lg .navbar-line-item:before{
843
+ border-bottom-width: 4px;
844
+ }
845
+ }
846
+
847
+ a.navbar-line-item{
848
+ --bs-link-color-rgb: 100, 122, 241;
849
+ }
850
+ .navbar-line-item{
851
+ position: relative;
852
+ @include flex-center();
853
+ --bs-navbar-nav-link-padding-x: 1.5rem;
854
+ color: var(--bs-nav-link-color);
855
+ &:before{
856
+ content: "";
857
+ position: absolute;
858
+ top: 0;
859
+ left: 100%;
860
+ width: 0;
861
+ height: 100%;
862
+ border-bottom: 2px solid var(--bs-link-color);
863
+ transition: $transition-base;
864
+ pointer-events: none;
865
+ z-index: 1;
866
+ }
867
+ &:hover{
868
+ background: $primary-bg-light;
869
+ &:before {
870
+ width: 100%;
871
+ left: 0;
872
+ }
873
+ ~ .navbar-line-item:before{
874
+ left: 0;
875
+ }
876
+ }
877
+ &:not(.active):hover:before{
878
+ border-color: $primary-sub-highlight;
879
+ }
880
+ &.active:before{
881
+ width: 100%;
882
+ left: 0;
883
+ }
884
+ }
885
+ // dropdown 版本
886
+ .navbar-line-item.dropdown{
887
+ padding: 0;
888
+ padding-left: 0 !important;
889
+ padding-right: 0 !important;
890
+ // (firefox 暫不支援)
891
+ &:has(.dropdown-toggle[aria-expanded="true"]){
892
+ background: $primary-bg-light;
893
+ &:before{
894
+ width: 100%;
895
+ left: 0;
896
+ border-bottom-color: $primary-sub-highlight;
897
+ }
898
+ }
899
+ &:not(.active) .dropdown-link{
900
+ color: var(--bs-nav-link-color);
901
+ }
902
+ .dropdown-link{
903
+ @include flex-center();
904
+ height: 100%;
905
+ padding: var(--bs-nav-link-padding-y) var(--bs-navbar-nav-link-padding-x);
906
+ }
907
+ .dropdown-toggle[aria-expanded="true"]{
908
+ color: $primary;
909
+ }
910
+ }
911
+
912
+
913
+ .navbar[data-bs-theme="dark"]{
914
+ --dark-theme-primary: #bec9ff;
915
+ .navbar-line-item.dropdown:not(.active) .dropdown-link{
916
+ color: var(--dark-theme-primary);
917
+ }
918
+ .navbar-nav .show > .nav-link, .navbar-nav .nav-link.active{
919
+ &, a{
920
+ color: $white;
921
+ }
922
+ }
923
+ .navbar-line-item:before{
924
+ border-bottom-color: var(--dark-theme-primary);
925
+ }
926
+ .navbar-line-item.dropdown:not(.active) .dropdown-link,
927
+ .navbar-line-item:before{
928
+ opacity: .9;
929
+ }
930
+ }
931
+ // 有底線的 tab bar ------------------------------------------
932
+
933
+
934
+
935
+ // 固定寬度 ------------------------------------------
936
+ .w-33{
937
+ width: 33.33%;
938
+ }
939
+ .w-66{
940
+ width: 66.66%;
941
+ }
942
+ @for $i from 1 through 25 {
943
+ .w-#{$i}rem {
944
+ width: #{$i}rem;
945
+ }
946
+ }
947
+
948
+ // 固定寬度 ------------------------------------------
949
+
950
+
951
+
952
+ // 無內容物 UI ------------------------------------------
953
+ .no-content{
954
+ padding-top: 10rem;
955
+ .content-img > .material-icons, p{
956
+ opacity: .7;
957
+ }
958
+ .content-img > .material-icons{
959
+ font-size: 6rem;
960
+ margin-bottom: 0.5rem;
961
+ opacity: .5;
962
+ }
963
+ p{
964
+ font-size: 1.25rem;
965
+ }
966
+ }
967
+ // 無內容物 UI ------------------------------------------
968
+
969
+
970
+
971
+ // 暫定:螢幕寬度小於 991px (含) 不可使用 ------------------------------------------
972
+ .mobile-forbidden{
973
+ display: none;
974
+ }
975
+ @media only screen and (max-width: 991px) {
976
+ body{
977
+ overflow: hidden;
978
+ }
979
+ .mobile-forbidden{
980
+ position: fixed;
981
+ top: 0;
982
+ left: 0;
983
+ right: 0;
984
+ bottom: 0;
985
+ margin: auto;
986
+ @include flex-center();
987
+ flex-direction: column;
988
+ padding: 2rem;
989
+ font-size: $font-size-lg;
990
+ text-align: center;
991
+ color: var(--gray-500);
992
+ background: $white $gradient-blue-light;
993
+ z-index: $zindex-max;
994
+ img {
995
+ width: 20rem;
996
+ }
997
+ }
998
+ }
999
+ // 暫定:螢幕寬度小於 991px (含) 不可使用 ------------------------------------------
1000
+
1001
+
1002
+
1003
+ // sweet alert ------------------------------------------
1004
+ .swal2-container{
1005
+ &.swal2-backdrop-show, &.swal2-noanimation{
1006
+ backdrop-filter: var(--backdrop-blur);
1007
+ }
1008
+ }
1009
+
1010
+ div:where(.swal2-container){
1011
+ .swal2-html-container{
1012
+ font-size: 1rem !important;
1013
+ color: var(--bs-body-color) !important;
1014
+ }
1015
+ h2:where(.swal2-title){
1016
+ font-size: 1.5rem !important;
1017
+ color: var(--bs-emphasis-color) !important;
1018
+ }
1019
+ .swal2-actions{
1020
+ flex-direction: row-reverse;
1021
+ width: 100%;
1022
+ }
1023
+ button:where(.swal2-styled){
1024
+ margin-left: .5rem !important;
1025
+ margin-right: .5rem !important;
1026
+ }
1027
+
1028
+ button:where(.swal2-styled).swal2-cancel{
1029
+ background-color: $secondary !important;
1030
+ }
1031
+ }
1032
1032
  // sweet alert ------------------------------------------