feat: print component

Fix #12

Merge branch 'print-screens' into version-2
main
Yanick Champoux 2022-04-02 18:38:12 -04:00
commit c56fe585a6
28 changed files with 451 additions and 206 deletions

View File

@ -2,7 +2,7 @@ const path = require("path");
const preprocess = require("svelte-preprocess"); const preprocess = require("svelte-preprocess");
module.exports = { module.exports = {
// core: { builder: "storybook-builder-vite" }, core: { builder: "storybook-builder-vite" },
staticDirs: ["../static", "../pictures"], staticDirs: ["../static", "../pictures"],
stories: [ stories: [
"../src/**/*.stories.mdx", "../src/**/*.stories.mdx",
@ -18,10 +18,14 @@ module.exports = {
preprocess: preprocess(), preprocess: preprocess(),
}, },
async viteFinal(config, { configType }) { async viteFinal(config, { configType }) {
if(!config.resolve.alias) config.resolve.alias = {};
// customize the Vite config here // customize the Vite config here
config.resolve.alias.$lib = path.resolve(__dirname, "../src/lib/"); config.resolve.alias.$lib = path.resolve(__dirname, "../src/lib/");
config.resolve.alias.$app = path.resolve(__dirname, "../fake/app/"); config.resolve.alias.$app = path.resolve(__dirname, "../fake/app/");
config.resolve.dedupe = ["@storybook/client-api"];
// return the customized config // return the customized config
return config; return config;
}, },

View File

@ -0,0 +1,5 @@
---
message: |
hygen {bold generator new} --name [NAME] --action [ACTION]
hygen {bold generator with-prompt} --name [NAME] --action [ACTION]
---

View File

@ -0,0 +1,18 @@
---
to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t
---
---
to: app/hello.js
---
const hello = ```
Hello!
This is your first hygen template.
Learn what it can do here:
https://github.com/jondot/hygen
```
console.log(hello)

View File

@ -0,0 +1,18 @@
---
to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t
---
---
to: app/hello.js
---
const hello = ```
Hello!
This is your first prompt based hygen template.
Learn what it can do here:
https://github.com/jondot/hygen
```
console.log(hello)

View File

@ -0,0 +1,14 @@
---
to: _templates/<%= name %>/<%= action || 'new' %>/prompt.js
---
// see types of prompts:
// https://github.com/enquirer/enquirer/tree/master/examples
//
module.exports = [
{
type: 'input',
name: 'message',
message: "What's your message?"
}
]

3
_templates/package.json Normal file
View File

@ -0,0 +1,3 @@
{
"type": "commonjs"
}

View File

@ -0,0 +1,13 @@
const path = require('path');
module.exports = {
params: ({ args }) => {
const storypath = args.path.replace( '.svelte', '.stories.svelte' );
const component = path.basename(args.path.replace('/index.svelte','')).replace('.svelte','');
const to = path.join(path.dirname(args.path), component + '.stories.svelte' );
return { storypath, component, to}
}
}

View File

@ -0,0 +1,21 @@
---
to: <%= to %>
---
<Meta title="<%= component %>" component={<%= component %>} argTypes={{}} />
<Story name="Primary" args={{}} />
<Template let:args>
<div style="width: 50em">
<<%= component %> />
</div>
</Template>
<script>
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import { action } from "@storybook/addon-actions";
import <%= component %> from './<%=
h.path.basename(path)
%>';
</script>

View File

@ -24,7 +24,7 @@
"eslint-plugin-svelte3": "^3.4.1", "eslint-plugin-svelte3": "^3.4.1",
"prettier": "~2.5.1", "prettier": "~2.5.1",
"prettier-plugin-svelte": "^2.6.0", "prettier-plugin-svelte": "^2.6.0",
"storybook-builder-vite": "0.1.17", "storybook-builder-vite": "0.1.21",
"svelte": "^3.46.4", "svelte": "^3.46.4",
"vite": "^2.7.0" "vite": "^2.7.0"
}, },

View File

@ -9,10 +9,14 @@
<div class:hide={activeTab !== 'json'}> <div class:hide={activeTab !== 'json'}>
<JsonOutput /> <JsonOutput />
</div> </div>
<div class:hide={activeTab !== 'print'}>
<PrintOutput ship={$state}/>
</div>
</main> </main>
<script> <script>
import { getContext } from 'svelte';
import { Modal, Card, Nav } from "svelte-chota"; import { Modal, Card, Nav } from "svelte-chota";
import Ribbon from "./Ribbon.svelte"; import Ribbon from "./Ribbon.svelte";
@ -20,9 +24,12 @@
import ShipEdit from "./ShipEdit/index.svelte"; import ShipEdit from "./ShipEdit/index.svelte";
import About from "./About.svelte"; import About from "./About.svelte";
import JsonOutput from './Output/Json.svelte'; import JsonOutput from './Output/Json.svelte';
import PrintOutput from './Output/Print/index.svelte';
let activeTab = 'editor'; let activeTab = 'editor';
$: console.log(activeTab); $: console.log(activeTab);
const {state} = getContext('ship');
</script> </script>
<style> <style>

View File

@ -1,7 +1,7 @@
<div class="layers"> <div class="layers">
{#each armour as layer (layer)} {#each armor as layer,i (i)}
<div class="layer"> <div class="layer">
{#each _.range(layer.rating) as i (i)} {#each Array.from({length: layer}) as j}
<div class="cell" /> <div class="cell" />
{/each} {/each}
</div> </div>
@ -11,9 +11,9 @@
<script> <script>
import _ from "lodash"; import _ from "lodash";
export let armour = []; export let armor = [];
console.log(armor)
$: console.log(armour);
</script> </script>
<style> <style>

View File

@ -0,0 +1,22 @@
<Meta title="Output/Print/Structure/Armor" component={Armor} argTypes={{
armor: {
type: 'object',
defaultValue: [2,4],
}
}} />
<Story name="Primary" args={{}} />
<Template let:args>
<div style="width: 50em">
<Armor {...args} />
</div>
</Template>
<script>
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import Armor from './Armor.svelte';
</script>

View File

@ -0,0 +1,20 @@
<Meta title="Output/Print/Structure/Integrity" component={Integrity} argTypes={{
shipMass: {defaultValue:50},
rating: {defaultValue:14},
advanced: {defaultValue:false},
}} />
<Story name="Primary" args={{}} />
<Story name="Advanced" args={{ advanced: true }} />
<Template let:args>
<div style="width: 50em">
<Integrity {...args} />
</div>
</Template>
<script>
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import Integrity from './index.svelte';
</script>

View File

@ -1,9 +1,9 @@
<div> <div>
{#each rows as row, i (i)} {#each rows as row, i (i)}
<div class="row"> <div class="row">
{#each row as item, j (j)} {#each row as threshold, j (j)}
<div class="cell"> <div class="cell">
{#if item} {#if threshold}
<img src="icons/crew-star.svg" alt="crew loss threshold" /> <img src="icons/crew-star.svg" alt="crew loss threshold" />
{/if} {/if}
</div> </div>
@ -13,9 +13,7 @@
</div> </div>
<script> <script>
import { ceil } from "$lib/dux/utils"; export let shipMass = 0;
export let ship_mass = 0;
export let rating = 0; export let rating = 0;
export let advanced = false; export let advanced = false;
@ -26,7 +24,7 @@
$: cells = Array(rating).fill(false); $: cells = Array(rating).fill(false);
let dcp; let dcp;
$: dcp = ceil(ship_mass / 20); $: dcp = Math.ceil(shipMass / 20);
$: cells = divide(cells, dcp) $: cells = divide(cells, dcp)
.map((g) => { .map((g) => {
@ -51,16 +49,18 @@
</script> </script>
<style> <style>
.row { .row {
} margin-bottom: 0.5em;
}
.cell { .cell {
display: inline-block; display: inline-block;
margin-right: 0.5em; margin-right: 0.5em;
width: 1em; width: 1.5em;
height: 1em; height: 1.5em;
border: 1px solid black; border: 1px solid black;
} }
img { img {
width: 1em; width: 1em;
margin-left: 0.2em;
} }
</style> </style>

View File

@ -9,7 +9,7 @@
<script> <script>
import Integrity from "./Integrity/index.svelte"; import Integrity from "./Integrity/index.svelte";
import Armour from "./Armour/index.svelte"; import Armour from "./Armor.svelte";
export let structure = {}; export let structure = {};
export let ship_mass = 0; export let ship_mass = 0;

View File

@ -1,47 +1,51 @@
<h1> <h1>
ship name: <div class="fill" /> ship name: <div class="fill" />
</h1> </h1>
<div class="details"> <div class="details">
<h2>{ship_class}-class, {ship_type}</h2> <h2>
<div class="reqs"> {#if shipClass}
<Cost {cost} /> {shipClass}-class,
&nbsp; {/if}
<Mass {mass} /> {shipType}</h2>
</div> <div class="reqs">
<Cost cost={cost} />
&nbsp;
<Mass mass={mass} />
</div>
</div> </div>
<script> <script>
import Cost from "../../../Cost.svelte"; import Cost from "../../../Cost.svelte";
import Mass from "$lib/components/Mass.svelte"; import Mass from "$lib/components/Mass.svelte";
export let ship_class; export let shipClass;
export let ship_type; export let shipType;
export let cost, export let cost = 0;
mass = (0, 0); export let mass = 0;
</script> </script>
<style> <style>
h1 { h1 {
width: 100%; width: 100%;
display: flex; display: flex;
font-size: var(--font-scale-8); font-size: var(--font-scale-8);
} }
h2 { h2 {
font-size: var(--font-scale-7); font-size: var(--font-scale-7);
flex: 1; flex: 1;
} }
.fill { .fill {
margin-left: 0.5em; margin-left: 0.5em;
display: inline-block; display: inline-block;
flex: 1; flex: 1;
border-bottom: 1px solid black; border-bottom: 1px solid black;
} }
.details { .details {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
} }
.reqs { .reqs {
display: flex; display: flex;
} }
</style> </style>

View File

@ -0,0 +1,23 @@
<Meta title="Output/Print" component={Print} argTypes={{
ship: {
type: 'object',
defaultValue: sample
}
}} />
<Story name="Primary" args={{}} />
<Template let:args>
<div style="width: 50em">
<Print ship={sample}/>
</div>
</Template>
<script>
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import { action } from "@storybook/addon-actions";
import sample from './sample.js';
import Print from './index.svelte';
</script>

View File

@ -0,0 +1,17 @@
<Meta title="Output/Print/Systems/Firecons" component={Firecons} argTypes={{
firecons: { defaultValue: 2, type: 'number' }
}} />
<Story name="Primary" args={{}} />
<Template let:args>
<div style="width: 50em">
<Firecons {...args}/>
</div>
</Template>
<script>
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import Firecons from './index.svelte';
</script>

View File

@ -1,11 +1,11 @@
<div> <div>
{#each _.range(firecons) as firecon} {#each range(1,firecons) as firecon}
<img class="firecon" src="icons/firecon.svg" alt="firecon" /> <img class="firecon" src="icons/firecon.svg" alt="firecon" />
{/each} {/each}
</div> </div>
<script> <script>
import _ from "lodash"; import {range} from "$lib/utils.js";
export let firecons = 0; export let firecons = 0;
</script> </script>

View File

@ -0,0 +1,18 @@
<Meta title="Output/Print/Systems/Screens" component={Screens} argTypes={{
standard: { defaultValue: 3 },
advanced: { defaultValue: 3 },
}} />
<Story name="Primary" args={{}} />
<Template let:args>
<div style="width: 50em">
<Screens {...args}/>
</div>
</Template>
<script>
import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
import Screens from './index.svelte';
</script>

View File

@ -1,14 +1,14 @@
<div> <div>
{#each _.range(standard) as i} {#each range(1,standard) as i}
<img src="icons/screen.svg" alt="screen" /> <img src="icons/screen.svg" alt="screen" />
{/each} {/each}
{#each _.range(advanced) as i} {#each range(1,advanced) as i}
<img src="icons/screen-advanced.svg" alt="advanced screen" /> <img src="icons/screen-advanced.svg" alt="advanced screen" />
{/each} {/each}
</div> </div>
<script> <script>
import _ from "lodash"; import {range} from "$lib/utils.js";
export let standard = 0; export let standard = 0;
export let advanced = 0; export let advanced = 0;

View File

@ -1,14 +1,14 @@
<div> <div>
<Arcs selected={arcs} size="40"> <Arcs selected={arcs} size="40">
<text x="50%" y="50%"> <text x="50%" y="50%">
{weapon_class} {weaponClass}
</text> </text>
</Arcs> </Arcs>
</div> </div>
<script> <script>
import Arcs from "$lib/components/Weapon/Arcs/index.svelte"; import Arcs from "$lib/components/ShipEdit/Weaponry/Weapon/Arcs.svelte";
export let weapon_class = 1; export let weaponClass = 1;
export let arcs = []; export let arcs = [];
</script> </script>

View File

@ -11,7 +11,7 @@
export let weapons = []; export let weapons = [];
let beams = []; let beams = [];
$: beams = weapons.filter(({ weapon_type }) => weapon_type === "beam"); $: beams = weapons.filter(({ type }) => type === "beam");
</script> </script>
<style> <style>

View File

@ -1,44 +1,76 @@
<aside class="ship-sheet" transition:fade>
<Identification {...ship.general} />
<Weapons weapons={ship.weaponry.weapons} /> <div class="print-output">
<Identification
<div class="section-2"> shipClass={ship.identification.shipClass}
<Hull structure={ship.structure} ship_mass={ship.general.mass} /> shipType={ship.identification.shipType}
cost={ship.reqs?.cost}
<Systems mass={ship.reqs?.mass}
firecons={ship.weaponry.firecons.nbr}
screens={ship.structure.screens}
/> />
</div>
<MainSystems ftl={ship.ftl.type} engine={ship.engine.rating} /> <div class="section-2">
</aside> <Hull
structure={ship.structure}
shipMass={ship.identification.mass}
/>
<Systems
firecons={ship.weaponry.firecons.nbr}
screens={ship.structure.screens}
/>
</div>
<Weapons weapons={ship.weaponry.weapons} />
<MainSystems
ftl={ship?.propulsion?.ftl}
engine={ship?.propulsion?.drive?.rating}
/>
</div>
<div class="notice">
Printing this page will only prints the ship sheet.
</div>
<script> <script>
import _ from "lodash"; import Identification from "./Identification/index.svelte";
import MainSystems from "./MainSystems/index.svelte";
import Hull from "./Hull/index.svelte";
import Weapons from "./Weapons/index.svelte";
import Systems from "./Systems/index.svelte";
import Identification from "./Identification/index.svelte"; export let ship = {};
import MainSystems from "./MainSystems/index.svelte";
import Hull from "./Hull/index.svelte";
import Weapons from "./Weapons/index.svelte";
import Systems from "./Systems/index.svelte";
export let ship;
import { fly, fade } from "svelte/transition";
</script> </script>
<style> <style>
.ship-sheet { .print-output {
width: 4.25in; width: 4.25in;
height: 5.5in; height: 5.5in;
border: 1px solid black; border: 1px solid black;
padding: 1em; padding: 1em;
} margin: 0px auto;
}
.section-2 { .section-2 {
display: flex; display: flex;
align-items: start; align-items: start;
} margin-right: 2em;
margin-left: 2em;
}
.notice {
font-style: italic;
margin-top: 1em;
text-align: right;
}
@media print {
:global(body > *) {
visibility: hidden;
}
.print-output {
visibility: visible;
}
}
</style> </style>

View File

@ -1,108 +1,105 @@
export default { export default {
ftl: { "identification": {
mass: 0, "shipType": "Scout",
cost: 0, "shipClass": "Blah",
type: "standard", "isCarrier": false,
"mass": 10
}, },
engine: { "propulsion": {
mass: 40, "drive": {
cost: 80, "reqs": {
rating: 6, "cost": 2,
advanced: false, "mass": 1
}, },
general: { "rating": 3,
ship_class: "Deviant", "advanced": true
name: "",
ship_type: "Battleship",
mass: 132,
used_mass: 131,
cost: 415,
},
weaponry: {
firecons: {
nbr: 5,
mass: 5,
cost: 20,
}, },
weapons: [ "ftl": {
{ "reqs": {
weapon_type: "submunition", "cost": 0,
arcs: ["F"], "mass": 0
mass: 1,
cost: 3,
id: 1,
}, },
{ "type": "none"
weapon_type: "beam", }
weapon_class: "2", },
arcs: ["A", "AS", "FS"], "structure": {
mass: 2, "hull": {
cost: 6, "reqs": {
id: 2, "cost": 2,
"mass": 1
}, },
{ "rating": 10,
weapon_type: "pds", "min": 1,
mass: 1, "max": 10
cost: 3, },
id: 3, "screens": {
"reqs": {
"cost": 0,
"mass": 0
}, },
"standard": 3,
"advanced": 2
},
"cargo": {
"reqs": {
"cost": 0,
"mass": 0
},
"space": 0
},
"streamlining": {
"reqs": {
"cost": 0,
"mass": 0
},
"type": "none"
},
"armor": {
"layers": [],
"reqs": {
"mass": 0,
"cost": 0
}
}
},
"carrier": {
"reqs": {
"cost": 0,
"mass": 0
},
"bays": 0,
"squadrons": []
},
"weaponry": {
"weapons": [
{
"id": 1,
"type": "beam",
"reqs": {
"mass": 1,
"cost": 3
},
"weaponClass": 1
}
], ],
adfc: { "firecons": {
rating: 0, "stations": 1,
cost: 0, "reqs": {
mass: 0, "cost": 4,
"mass": 1
}
}, },
"adfc": {
"rating": 1,
"reqs": {
"cost": 8,
"mass": 2
}
}
}, },
structure: { "reqs": {
mass: 0, "cost": 19,
cost: 0, "mass": 10,
hull: { "usedMass": 6
rating: 22, }
advanced: false, }
cost: 44,
mass: 22,
},
screens: {
standard: 2,
advanced: 1,
cost: 105,
mass: 35,
},
armour: [
{
layer: 1,
rating: 7,
cost: 14,
mass: 14,
},
{
layer: 2,
rating: 2,
cost: 8,
mass: 4,
},
{
layer: 3,
rating: 0,
cost: 0,
mass: 0,
},
],
},
cargo: {
space: 7,
cost: 0,
mass: 7,
},
streamlining: {
type: "none",
cost: 0,
mass: 0,
},
carrier: {
bays: 0,
cost: 0,
mass: 0,
squadrons: [],
},
};

View File

@ -1,13 +0,0 @@
import Print from "./index.svelte";
import sample from "./sample";
export default {
title: "printouts",
};
export const basic = () => ({
Component: Print,
props: {
ship: sample,
},
});

View File

@ -3,6 +3,20 @@ import u from "updeep";
import reqs from "../reqs.js"; import reqs from "../reqs.js";
const schema = {
type: 'object',
properties: {
reqs: { type: 'object', properties: {
cost: { type: 'number' },
mass: { type: 'number' },
} },
layers: { type: 'array', items: 'number' }
},
examples: [
{ reqs: { cost: 5, mass: 5 }, layers: [2,4 ] }
]
}
const dux = new Updux({ const dux = new Updux({
subduxes: { subduxes: {
reqs, reqs,

8
src/lib/utils.js Normal file
View File

@ -0,0 +1,8 @@
export function range(min, max) {
if(max === undefined) {
max = min;
min = 0;
}
return Array.from({length: 1+max - min}).map( (_d,i) => i+ min);
}