feat: print component

Fix #12

Merge branch 'print-screens' into version-2
This commit is contained in:
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) => {
@ -52,15 +50,17 @@
<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

@ -3,11 +3,15 @@
</h1> </h1>
<div class="details"> <div class="details">
<h2>{ship_class}-class, {ship_type}</h2> <h2>
{#if shipClass}
{shipClass}-class,
{/if}
{shipType}</h2>
<div class="reqs"> <div class="reqs">
<Cost {cost} /> <Cost cost={cost} />
&nbsp; &nbsp;
<Mass {mass} /> <Mass mass={mass} />
</div> </div>
</div> </div>
@ -15,10 +19,10 @@
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>

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,10 +1,17 @@
<aside class="ship-sheet" transition:fade>
<Identification {...ship.general} />
<Weapons weapons={ship.weaponry.weapons} /> <div class="print-output">
<Identification
shipClass={ship.identification.shipClass}
shipType={ship.identification.shipType}
cost={ship.reqs?.cost}
mass={ship.reqs?.mass}
/>
<div class="section-2"> <div class="section-2">
<Hull structure={ship.structure} ship_mass={ship.general.mass} /> <Hull
structure={ship.structure}
shipMass={ship.identification.mass}
/>
<Systems <Systems
firecons={ship.weaponry.firecons.nbr} firecons={ship.weaponry.firecons.nbr}
@ -12,33 +19,58 @@
/> />
</div> </div>
<MainSystems ftl={ship.ftl.type} engine={ship.engine.rating} /> <Weapons weapons={ship.weaponry.weapons} />
</aside>
<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 Identification from "./Identification/index.svelte";
import MainSystems from "./MainSystems/index.svelte"; import MainSystems from "./MainSystems/index.svelte";
import Hull from "./Hull/index.svelte"; import Hull from "./Hull/index.svelte";
import Weapons from "./Weapons/index.svelte"; import Weapons from "./Weapons/index.svelte";
import Systems from "./Systems/index.svelte"; import Systems from "./Systems/index.svelte";
export let ship; 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: { "ftl": {
firecons: { "reqs": {
nbr: 5, "cost": 0,
mass: 5, "mass": 0
cost: 20,
}, },
weapons: [ "type": "none"
}
},
"structure": {
"hull": {
"reqs": {
"cost": 2,
"mass": 1
},
"rating": 10,
"min": 1,
"max": 10
},
"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": [
{ {
weapon_type: "submunition", "id": 1,
arcs: ["F"], "type": "beam",
mass: 1, "reqs": {
cost: 3, "mass": 1,
id: 1, "cost": 3
},
{
weapon_type: "beam",
weapon_class: "2",
arcs: ["A", "AS", "FS"],
mass: 2,
cost: 6,
id: 2,
},
{
weapon_type: "pds",
mass: 1,
cost: 3,
id: 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);
}