@jjlmoya/utils-pets 1.9.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-pets",
3
- "version": "1.9.0",
3
+ "version": "1.11.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
7
7
  "exports": {
8
8
  ".": "./src/index.ts",
9
- "./data": "./src/data.ts"
9
+ "./data": "./src/data.ts",
10
+ "./entries": "./src/entries.ts"
10
11
  },
11
12
  "files": [
12
- "src"
13
+ "src",
14
+ "scripts"
13
15
  ],
14
16
  "publishConfig": {
15
17
  "access": "public"
@@ -28,7 +30,8 @@
28
30
  "postversion": "git push && git push --tags",
29
31
  "patch": "npm version patch",
30
32
  "minor": "npm version minor",
31
- "major": "npm version major"
33
+ "major": "npm version major",
34
+ "postinstall": "node scripts/postinstall.mjs"
32
35
  },
33
36
  "lint-staged": {
34
37
  "*.{ts,tsx,astro}": [
@@ -0,0 +1,27 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const libDir = dirname(fileURLToPath(import.meta.url));
6
+ const toolsDir = join(libDir, '../src/tool');
7
+
8
+ const inNodeModules = libDir.includes('node_modules');
9
+ if (!inNodeModules) process.exit(0);
10
+
11
+ const projectRoot = join(libDir, '../../../..');
12
+ const categoryKey = JSON.parse(readFileSync(join(libDir, '../package.json'), 'utf8')).name.replace('@jjlmoya/utils-', '');
13
+ const destDir = join(projectRoot, `public/styles/lib/${categoryKey}`);
14
+
15
+ mkdirSync(destDir, { recursive: true });
16
+
17
+ const tools = readdirSync(toolsDir, { withFileTypes: true }).filter(d => d.isDirectory());
18
+ for (const tool of tools) {
19
+ const toolDir = join(toolsDir, tool.name);
20
+ let files;
21
+ try { files = readdirSync(toolDir).filter(f => f.endsWith('.css')); }
22
+ catch { continue; }
23
+ for (const file of files) {
24
+ writeFileSync(join(destDir, file), readFileSync(join(toolDir, file)));
25
+ console.log(`[@jjlmoya/utils-${categoryKey}] copied ${file}`);
26
+ }
27
+ }
@@ -1,6 +1,6 @@
1
1
  import type { PetCategoryEntry } from '../types';
2
- import { petAge } from '../tool/petAge';
3
- import { petRation } from '../tool/petRation';
2
+ import { petAge } from '../tool/petAge/entry';
3
+ import { petRation } from '../tool/petRation/entry';
4
4
 
5
5
  export const petsCategory: PetCategoryEntry = {
6
6
  icon: 'mdi:paw',
package/src/entries.ts ADDED
@@ -0,0 +1,8 @@
1
+ export { petAge } from './tool/petAge/entry';
2
+ export type { PetAgeUI, PetAgeLocaleContent } from './tool/petAge/entry';
3
+ export { petRation } from './tool/petRation/entry';
4
+ export type { PetRationUI, PetRationLocaleContent } from './tool/petRation/entry';
5
+ export { petsCategory } from './category';
6
+ import { petAge } from './tool/petAge/entry';
7
+ import { petRation } from './tool/petRation/entry';
8
+ export const ALL_ENTRIES = [petAge, petRation];
@@ -305,655 +305,3 @@ const { ui } = Astro.props;
305
305
  document.addEventListener("astro:page-load", initPetAge);
306
306
  </script>
307
307
 
308
- <style>
309
- .hidden {
310
- display: none;
311
- }
312
-
313
- .pet-age-calculator {
314
- position: relative;
315
- max-width: 650px;
316
- margin: 2rem auto;
317
- background: var(--color-surface, #fff);
318
- border-radius: 2rem;
319
- padding: 2.5rem;
320
- box-shadow: 0 20px 50px -15px rgba(0, 0, 0, 0.08);
321
- color: var(--color-text, #334155);
322
- border: 1px solid var(--color-border, #f1f5f9);
323
- min-height: 400px;
324
- }
325
-
326
- :global(.theme-dark) .pet-age-calculator {
327
- background: var(--color-surface-dark, #1e293b);
328
- color: var(--color-text-dark, #e2e8f0);
329
- border-color: var(--color-border-dark, #334155);
330
- box-shadow: 0 20px 50px -15px rgba(0, 0, 0, 0.3);
331
- }
332
-
333
- .age-loader {
334
- position: absolute;
335
- top: 0;
336
- left: 0;
337
- width: 100%;
338
- height: 100%;
339
- background: var(--color-surface, #fff);
340
- display: flex;
341
- align-items: center;
342
- justify-content: center;
343
- border-radius: 2rem;
344
- z-index: 50;
345
- transition:
346
- opacity 0.4s cubic-bezier(0.4, 0, 0.2, 1),
347
- visibility 0.4s;
348
- }
349
-
350
- :global(.theme-dark) .age-loader {
351
- background: var(--color-surface-dark, #1e293b);
352
- }
353
-
354
- .age-loader.hidden {
355
- opacity: 0;
356
- visibility: hidden;
357
- pointer-events: none;
358
- }
359
-
360
- .age-loader-spinner {
361
- width: 3rem;
362
- height: 3rem;
363
- color: var(--color-accent, #f59e0b);
364
- animation: age-spin 2s infinite linear;
365
- }
366
-
367
- @keyframes age-spin {
368
- from {
369
- transform: rotate(0deg);
370
- }
371
- to {
372
- transform: rotate(360deg);
373
- }
374
- }
375
-
376
- .age-container {
377
- display: flex;
378
- flex-direction: column;
379
- gap: 3rem;
380
- animation: age-fade-up 0.6s cubic-bezier(0.4, 0, 0.2, 1);
381
- }
382
-
383
- @keyframes age-fade-up {
384
- from {
385
- opacity: 0;
386
- transform: translateY(10px);
387
- }
388
- to {
389
- opacity: 1;
390
- transform: translateY(0);
391
- }
392
- }
393
-
394
- .age-section {
395
- border-bottom: 1px dashed var(--color-border-dashed, #e2e8f0);
396
- padding-bottom: 2rem;
397
- }
398
-
399
- .age-section:last-of-type {
400
- border-bottom: none;
401
- }
402
-
403
- :global(.theme-dark) .age-section {
404
- border-bottom-color: var(--color-border-dark, #334155);
405
- }
406
-
407
- .age-section-title {
408
- font-size: 1.1rem;
409
- font-weight: 950;
410
- color: var(--color-heading, #0f172a);
411
- margin-bottom: 2rem;
412
- display: flex;
413
- align-items: center;
414
- gap: 0.75rem;
415
- text-transform: uppercase;
416
- letter-spacing: 0.05em;
417
- }
418
-
419
- :global(.theme-dark) .age-section-title {
420
- color: var(--color-heading-dark, #f8fafc);
421
- }
422
-
423
- .age-section-title svg {
424
- width: 1.25rem;
425
- height: 1.25rem;
426
- }
427
-
428
- .age-input-item {
429
- margin-bottom: 2rem;
430
- }
431
-
432
- .age-input-item:last-child {
433
- margin-bottom: 0;
434
- }
435
-
436
- .age-label {
437
- display: block;
438
- font-size: 0.75rem;
439
- font-weight: 800;
440
- text-transform: uppercase;
441
- color: var(--color-label, #94a3b8);
442
- margin-bottom: 1rem;
443
- letter-spacing: 0.1em;
444
- }
445
-
446
- .age-text-input {
447
- width: 100%;
448
- padding: 0.875rem 1.25rem;
449
- background: var(--color-btn-bg, #f8fafc);
450
- border: 2px solid var(--color-btn-border, #e2e8f0);
451
- border-radius: 1rem;
452
- font-size: 1rem;
453
- font-weight: 700;
454
- color: var(--color-text, #334155);
455
- outline: none;
456
- transition:
457
- border-color 0.2s,
458
- box-shadow 0.2s;
459
- box-sizing: border-box;
460
- }
461
-
462
- .age-text-input::placeholder {
463
- color: var(--color-label, #94a3b8);
464
- font-weight: 500;
465
- }
466
-
467
- .age-text-input:focus {
468
- border-color: var(--color-accent, #f59e0b);
469
- box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.1);
470
- }
471
-
472
- :global(.theme-dark) .age-text-input {
473
- background: var(--color-btn-bg-dark, #0f172a);
474
- border-color: var(--color-btn-border-dark, #334155);
475
- color: var(--color-text-dark, #e2e8f0);
476
- }
477
-
478
- .age-species-selector {
479
- display: flex;
480
- gap: 1rem;
481
- }
482
-
483
- .pet-type-btn {
484
- flex: 1;
485
- display: flex;
486
- align-items: center;
487
- justify-content: center;
488
- gap: 0.5rem;
489
- padding: 1.25rem 0.75rem;
490
- background: var(--color-btn-bg, #f8fafc);
491
- border: 2px solid var(--color-btn-border, #e2e8f0);
492
- border-radius: 1rem;
493
- cursor: pointer;
494
- font-weight: 800;
495
- font-size: 1rem;
496
- color: var(--color-text, #334155);
497
- transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
498
- }
499
-
500
- :global(.theme-dark) .pet-type-btn {
501
- background: var(--color-btn-bg-dark, #0f172a);
502
- border-color: var(--color-btn-border-dark, #334155);
503
- color: var(--color-text-dark, #e2e8f0);
504
- }
505
-
506
- .pet-type-btn.active {
507
- background: var(--color-surface, #fff);
508
- border-color: var(--color-accent, #f59e0b);
509
- color: var(--color-accent, #f59e0b);
510
- box-shadow: 0 4px 15px rgba(245, 158, 11, 0.15);
511
- transform: translateY(-2px);
512
- }
513
-
514
- :global(.theme-dark) .pet-type-btn.active {
515
- background: var(--color-surface-elevated-dark, #1e293b);
516
- }
517
-
518
- .age-icon {
519
- width: 1.5rem;
520
- height: 1.5rem;
521
- }
522
-
523
- .age-segmented {
524
- display: flex;
525
- background: var(--color-btn-bg, #f8fafc);
526
- padding: 6px;
527
- border-radius: 1rem;
528
- border: 1px solid var(--color-btn-border, #e2e8f0);
529
- }
530
-
531
- :global(.theme-dark) .age-segmented {
532
- background: var(--color-btn-bg-dark, #0f172a);
533
- border-color: var(--color-btn-border-dark, #334155);
534
- }
535
-
536
- .size-btn {
537
- flex: 1;
538
- text-align: center;
539
- padding: 0.85rem;
540
- border-radius: 0.75rem;
541
- cursor: pointer;
542
- font-weight: 700;
543
- font-size: 0.85rem;
544
- border: none;
545
- background: transparent;
546
- color: var(--color-muted, #64748b);
547
- transition: all 0.2s;
548
- }
549
-
550
- .size-btn.active {
551
- background: var(--color-accent, #f59e0b);
552
- color: var(--color-on-accent, #fff);
553
- box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);
554
- }
555
-
556
- .age-year-wrap {
557
- display: flex;
558
- justify-content: center;
559
- }
560
-
561
- .age-year-input {
562
- width: 200px;
563
- text-align: center;
564
- padding: 1rem;
565
- background: var(--color-btn-bg, #f8fafc);
566
- border: 2px solid var(--color-btn-border, #e2e8f0);
567
- border-radius: 1rem;
568
- font-size: 2.5rem;
569
- font-weight: 900;
570
- color: var(--color-text, #334155);
571
- outline: none;
572
- transition:
573
- border-color 0.2s,
574
- box-shadow 0.2s;
575
- box-sizing: border-box;
576
- }
577
-
578
- .age-year-input::placeholder {
579
- color: var(--color-label, #94a3b8);
580
- font-weight: 400;
581
- font-size: 1rem;
582
- }
583
-
584
- .age-year-input:focus,
585
- .age-year-input.age-input-valid {
586
- border-color: var(--color-accent, #f59e0b);
587
- box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.1);
588
- }
589
-
590
- .age-year-input.age-input-error {
591
- border-color: #ef4444;
592
- box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.1);
593
- }
594
-
595
- :global(.theme-dark) .age-year-input {
596
- background: var(--color-btn-bg-dark, #0f172a);
597
- border-color: var(--color-btn-border-dark, #334155);
598
- color: var(--color-text-dark, #e2e8f0);
599
- }
600
-
601
- .age-year-input::-webkit-inner-spin-button,
602
- .age-year-input::-webkit-outer-spin-button {
603
- -webkit-appearance: none;
604
- margin: 0;
605
- }
606
- .age-year-input[type="number"] {
607
- -moz-appearance: textfield;
608
- }
609
-
610
- .age-results {
611
- background: var(--color-results-bg, #0f172a);
612
- border-radius: 2rem;
613
- padding: 2.5rem;
614
- color: var(--color-results-text, #fff);
615
- box-shadow: 0 20px 40px -10px rgba(15, 23, 42, 0.3);
616
- }
617
-
618
- :global(.theme-dark) .age-results {
619
- background: var(--color-accent, #f59e0b);
620
- color: var(--color-results-text-dark, #0f172a);
621
- box-shadow: 0 20px 40px -10px rgba(245, 158, 11, 0.2);
622
- }
623
-
624
- .age-res-main {
625
- text-align: center;
626
- margin-bottom: 1.5rem;
627
- }
628
-
629
- .age-res-label {
630
- display: block;
631
- font-size: 0.8rem;
632
- font-weight: 900;
633
- text-transform: uppercase;
634
- color: var(--color-accent, #f59e0b);
635
- letter-spacing: 0.15em;
636
- margin-bottom: 0.5rem;
637
- }
638
-
639
- :global(.theme-dark) .age-res-label {
640
- color: var(--color-results-bg, #0f172a);
641
- opacity: 0.7;
642
- }
643
-
644
- .age-res-number {
645
- font-size: 5rem;
646
- font-weight: 950;
647
- line-height: 1;
648
- display: flex;
649
- align-items: baseline;
650
- justify-content: center;
651
- gap: 0.5rem;
652
- }
653
-
654
- .age-res-number small {
655
- font-size: 1.5rem;
656
- font-weight: 700;
657
- opacity: 0.6;
658
- }
659
-
660
- .age-res-divider {
661
- height: 1px;
662
- background: rgba(255, 255, 255, 0.1);
663
- margin: 1.5rem 0;
664
- }
665
-
666
- :global(.theme-dark) .age-res-divider {
667
- background: rgba(0, 0, 0, 0.1);
668
- }
669
-
670
- .age-res-grid {
671
- display: grid;
672
- grid-template-columns: 1fr 1fr;
673
- gap: 1rem;
674
- margin-bottom: 1.5rem;
675
- }
676
-
677
- .age-res-card {
678
- background: rgba(255, 255, 255, 0.08);
679
- border: 1px solid rgba(255, 255, 255, 0.1);
680
- border-radius: 1rem;
681
- padding: 1rem;
682
- display: flex;
683
- flex-direction: column;
684
- align-items: center;
685
- gap: 0.5rem;
686
- text-align: center;
687
- }
688
-
689
- :global(.theme-dark) .age-res-card {
690
- background: rgba(0, 0, 0, 0.1);
691
- border-color: rgba(0, 0, 0, 0.1);
692
- }
693
-
694
- .age-res-card-label {
695
- font-size: 0.7rem;
696
- font-weight: 900;
697
- text-transform: uppercase;
698
- letter-spacing: 0.1em;
699
- opacity: 0.6;
700
- }
701
-
702
- .age-res-card-val {
703
- font-size: 0.9rem;
704
- font-weight: 700;
705
- line-height: 1.2;
706
- }
707
-
708
- .age-res-footer {
709
- display: flex;
710
- justify-content: center;
711
- padding-top: 1.5rem;
712
- border-top: 1px solid rgba(255, 255, 255, 0.1);
713
- }
714
-
715
- :global(.theme-dark) .age-res-footer {
716
- border-top-color: rgba(0, 0, 0, 0.1);
717
- }
718
-
719
- .age-share-btn {
720
- display: flex;
721
- align-items: center;
722
- gap: 0.5rem;
723
- background: rgba(255, 255, 255, 0.1);
724
- border: 1px solid rgba(255, 255, 255, 0.2);
725
- color: #fff;
726
- padding: 0.75rem 1.5rem;
727
- border-radius: 2rem;
728
- font-weight: 700;
729
- font-size: 0.85rem;
730
- cursor: pointer;
731
- transition: all 0.2s;
732
- }
733
-
734
- .age-share-btn:hover {
735
- background: rgba(255, 255, 255, 0.2);
736
- }
737
-
738
- :global(.theme-dark) .age-share-btn {
739
- background: rgba(0, 0, 0, 0.15);
740
- border-color: rgba(0, 0, 0, 0.2);
741
- color: var(--color-results-bg, #0f172a);
742
- }
743
-
744
- .age-share-btn.age-btn-success {
745
- background: rgba(255, 255, 255, 0.25);
746
- }
747
-
748
- .age-icon-sm {
749
- width: 1rem;
750
- height: 1rem;
751
- }
752
-
753
- .age-share-overlay {
754
- position: fixed;
755
- inset: 0;
756
- z-index: 100;
757
- display: none;
758
- flex-direction: column;
759
- align-items: center;
760
- justify-content: center;
761
- background: #0f172a;
762
- padding: 1.5rem;
763
- }
764
-
765
- .age-share-overlay.visible {
766
- display: flex;
767
- }
768
-
769
- .age-share-wrap {
770
- width: 100%;
771
- max-width: 420px;
772
- display: flex;
773
- flex-direction: column;
774
- align-items: center;
775
- gap: 2rem;
776
- }
777
-
778
- .age-share-card {
779
- width: 100%;
780
- background: rgba(255, 255, 255, 0.05);
781
- border: 1px solid rgba(255, 255, 255, 0.1);
782
- border-radius: 2.5rem;
783
- overflow: hidden;
784
- color: #fff;
785
- }
786
-
787
- .age-share-card-header {
788
- padding: 2rem;
789
- display: flex;
790
- flex-direction: column;
791
- align-items: center;
792
- gap: 1rem;
793
- border-bottom: 1px solid rgba(255, 255, 255, 0.05);
794
- }
795
-
796
- .age-share-badge {
797
- background: rgba(99, 102, 241, 0.8);
798
- color: #fff;
799
- font-size: 0.65rem;
800
- font-weight: 900;
801
- text-transform: uppercase;
802
- letter-spacing: 0.2em;
803
- padding: 0.4rem 1rem;
804
- border-radius: 2rem;
805
- }
806
-
807
- .age-share-animal {
808
- width: 5rem;
809
- height: 5rem;
810
- background: rgba(15, 23, 42, 0.8);
811
- border-radius: 50%;
812
- border: 2px solid rgba(255, 255, 255, 0.15);
813
- display: flex;
814
- align-items: center;
815
- justify-content: center;
816
- color: #a5b4fc;
817
- }
818
-
819
- .age-share-animal svg {
820
- width: 3rem;
821
- height: 3rem;
822
- }
823
-
824
- #share-pet-name {
825
- font-size: 2rem;
826
- font-weight: 900;
827
- text-align: center;
828
- color: #fff;
829
- margin: 0;
830
- }
831
-
832
- .age-share-card-body {
833
- padding: 2rem;
834
- display: flex;
835
- flex-direction: column;
836
- align-items: center;
837
- gap: 0.75rem;
838
- }
839
-
840
- .age-share-human-label {
841
- font-size: 0.7rem;
842
- font-weight: 900;
843
- text-transform: uppercase;
844
- letter-spacing: 0.2em;
845
- color: rgba(165, 180, 252, 0.7);
846
- }
847
-
848
- #share-human-age {
849
- font-size: 7rem;
850
- font-weight: 900;
851
- line-height: 0.9;
852
- color: #fff;
853
- }
854
-
855
- .age-share-years-label {
856
- font-size: 1.5rem;
857
- font-weight: 900;
858
- text-transform: uppercase;
859
- letter-spacing: 0.1em;
860
- color: rgba(255, 255, 255, 0.4);
861
- margin-top: -0.5rem;
862
- }
863
-
864
- .age-share-info-grid {
865
- display: grid;
866
- grid-template-columns: 1fr 1fr;
867
- gap: 0.75rem;
868
- width: 100%;
869
- margin-top: 0.75rem;
870
- }
871
-
872
- .age-share-info-item {
873
- background: rgba(255, 255, 255, 0.05);
874
- border: 1px solid rgba(255, 255, 255, 0.05);
875
- border-radius: 1rem;
876
- padding: 0.75rem;
877
- display: flex;
878
- flex-direction: column;
879
- align-items: center;
880
- gap: 0.25rem;
881
- text-align: center;
882
- }
883
-
884
- .age-share-info-label {
885
- font-size: 0.65rem;
886
- font-weight: 900;
887
- text-transform: uppercase;
888
- letter-spacing: 0.1em;
889
- color: rgba(165, 180, 252, 0.5);
890
- }
891
-
892
- .age-share-info-val {
893
- font-size: 0.85rem;
894
- font-weight: 700;
895
- color: #fff;
896
- }
897
-
898
- .age-share-card-footer {
899
- padding: 1rem;
900
- background: rgba(0, 0, 0, 0.2);
901
- border-top: 1px solid rgba(255, 255, 255, 0.05);
902
- text-align: center;
903
- font-size: 0.65rem;
904
- font-weight: 900;
905
- letter-spacing: 0.3em;
906
- text-transform: uppercase;
907
- color: rgba(255, 255, 255, 0.3);
908
- }
909
-
910
- .age-share-new-btn {
911
- display: flex;
912
- align-items: center;
913
- gap: 0.5rem;
914
- background: rgba(255, 255, 255, 0.05);
915
- border: 1px solid rgba(255, 255, 255, 0.1);
916
- color: rgba(255, 255, 255, 0.6);
917
- padding: 0.75rem 1.5rem;
918
- border-radius: 2rem;
919
- font-size: 0.75rem;
920
- font-weight: 700;
921
- text-transform: uppercase;
922
- letter-spacing: 0.1em;
923
- cursor: pointer;
924
- transition: all 0.2s;
925
- }
926
-
927
- .age-share-new-btn:hover {
928
- background: rgba(255, 255, 255, 0.1);
929
- color: #fff;
930
- }
931
-
932
- .age-share-new-btn svg {
933
- width: 1rem;
934
- height: 1rem;
935
- }
936
-
937
- @media (max-width: 600px) {
938
- .pet-age-calculator {
939
- padding: 1.5rem;
940
- margin: 1rem;
941
- }
942
-
943
- .age-species-selector {
944
- flex-direction: column;
945
- }
946
-
947
- .age-res-grid {
948
- grid-template-columns: 1fr;
949
- }
950
-
951
- .age-res-number {
952
- font-size: 4rem;
953
- }
954
-
955
- .age-year-input {
956
- font-size: 2rem;
957
- }
958
- }
959
- </style>